I hope I am not repeating an existing question, I have tried really hard to find what I need on the site, but now feel I need to ask the question, so here goes, I hope you guys can help me out :s
I have an array;
var 1Results = somecontent;
var 2Results = somecontent;
var 3Results = somecontent;
var 4Results = somecontent;
var nomResults = 1Results + 2Results + 3Results + 4Results;
I have a script that is supposed to weed out the duplicate numbers and display them (in sorted_arr);
var arr = nomResults;
var sorted_arr = arr.sort(); // You can define the comparing function here.
// JS by default uses a crappy string compare.
var results = [];
for (var i = 0; i < arr.length - 1; i++) {
if (sorted_arr[i + 1] == sorted_arr[i]) {
results.push(sorted_arr[i]);
}
}
This script doesn't work, however is I change the script to this;
var arr = [9, 9, 111, 2, 3, 4, 4, 5, 7];
var sorted_arr = arr.sort(); // You can define the comparing function here.
// JS by default uses a crappy string compare.
var results = [];
for (var i = 0; i < arr.length - 1; i++) {
if (sorted_arr[i + 1] == sorted_arr[i]) {
results.push(sorted_arr[i]);
}
}
It works fine, any ideas why .sort() won't work with my pre popluated array?
Any help would be greatly appreciated.
You have to use brackets notation to add elements to your new Array like :
var arr = [Results1, Results2...];
Or Array.prototype.push() :
var arr = [];
arr.push(Results1);
arr.push(Results2);
//...
Plus you can use a specific function for sorting, either declaring a new function compare :
function compare(a, b) {
return a - b;
}
Which will use actual values of your array (and not Strings, as specified in your comments).
Then you pass it to sort :
arr = arr.sort(compare);
Or directly use anonymous function, if you don't need it more than one time :
arr = arr.sort(function(a, b) {
return a - b;
});
Two issues I can see in your code.
The variable names must not begin with a number
var nomResults is not an array but a string
The below code works for me just fine-
var results1 = "this",
results2="is",
results3="an",
results4="array",
theArray = [results1, results2, results3, results4];
console.log(theArray);
["this", "is", "an", "array"]
console.log(theArray.sort());
["an", "array", "is", "this"]
I was building my array wrong!!! Thanks guys, I knew it would be something simple :)
Instead of this;
var nomResults = 1Results + 2Results + 3Results + 4Results;
I needed to do this;
var nomResults = [Results1, Results2, Results3, Results4];
I've been looking at this for so long, I didn't see it. My script is all working now and great, errors are all gone, this is amazing. Many props and thanks to #jpreynat Thank you SO much :) I need a holiday....
Related
I'm new to JS and am trying to create a simple 'swap array elements if array A element is bigger than array B element' function. In the swapIndexes function, I don't understand why I can't define the variables as shown in the comments. For example, it works if it state arrA[c] rather than let a = arrA[c].
Why does this happen? Can anyone give some beginner tips on how best to go about something like this? My code feels verbose. Thanks for any help here.
var arrA = [0, 1, 2, 7, 6],
arrB = [0, 1, 2, 5, 7],
indexesToSwap = [],
aValuesToSwap = [],
bValuesToSwap = [],
needSwapping = false;
arrA.forEach(getSwappableIndexesAndValues);
indexesToSwap.forEach(swapIndexes);
function getSwappableIndexesAndValues(c, i) {
let b = arrB[i];
if (c > b) {
needSwapping = true;
indexesToSwap.push(i);
aValuesToSwap.push(b);
bValuesToSwap.push(c);
}
}
function swapIndexes(c, i) {
//let a = arrA[c]; fails why???
//let b = arrB[c]; fails why???
//a = aValuesToSwap[i]; fails why???
//b = bValuesToSwap[i]; fails why???
arrA[c] = aValuesToSwap[i];
arrB[c] = bValuesToSwap[i];
}
console.log(arrA);
console.log(arrB);
In javascript, when you create a variable from a given index in an array, This will create a new memory space containing a copy of the value at this index. The newly created variable will not point to the content of the array and thus, modifying this variable will not modify the content of the array.
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/let
indexesToSwap has all the information you need to swap. The swap value arrays (aValuesToSwap, bValuesToSwap) are greatly complicating matters and are wholly unnecessary.
Regardless of the values to swap arrays, swapping is a fundamental operation and typically involves a simple temporary, e.g.
temp = arrA[i];
arrA[i] = arrB[i];
arrB[i] = temp;
Discarding the complexities, here's an alternative to the function getSwappableIndexesAndValues
function getSwappableIndexes(c, i) {
if (c > arrB[i])
indexesToSwap.push(i);
}
And a simplified swap function
function swapIndexes(c, i) {
let temp = arrA[c];
arrA[c] = arrB[c];
arrB[c] = temp;
}
I have to say further though that the use of Array.forEach wildly complicates the entire solution. Unless this is an assignment, using a simple for-loop is best here.
// swaps values between arrays where the value in
// array a is greater than the value in array b
//
function swapIfGreaterThan(a,b) {
for(let i = 0; i < a.length && i < b.length; i++) {
if(a[i] > b[i]) {
let temp = a[i];
a[i] = b[i];
b[i] = temp;
}
}
}
var arrA = [0, 1, 2, 7, 6],
arrB = [0, 1, 2, 5, 7],
indexesToSwap = [],
aValuesToSwap = [],
bValuesToSwap = [],
needSwapping = false;
arrA.forEach(getSwappableIndexesAndValues);
indexesToSwap.forEach(swapIndexes);
function getSwappableIndexesAndValues(c, i) {
let b = arrB[i];
if (c > b) {
needSwapping = true;
indexesToSwap.push(i);
aValuesToSwap.push(b);
bValuesToSwap.push(c);
}
}
function swapIndexes(c, i) {
//let a = arrA[c]; fails why???
//let b = arrB[c]; fails why???
//a = aValuesToSwap[i]; fails why???
//b = bValuesToSwap[i]; fails why???
arrA[c] = bValuesToSwap[i];
arrB[c] =aValuesToSwap[i];
console.log( arrA[c], arrB[c]);
console.log( aValuesToSwap[i], bValuesToSwap[i]);
}
console.log(arrA);
console.log(arrB);
It is not possible array values and primitive data type values are different. If you try with the array of the object your attempt will be correct.
I've developed this codepen (http://codepen.io/PiotrBerebecki/pen/qZjojV?editors=0010) trying to solve the following JavaScript problem:
Given a non-negative integer, return an array containing a list of independent digits in reverse order.
Example:
348597 => The correct solution should be [7,9,5,8,4,3]
The function below apparently is incorrect as it returns ["7", "9", "5", "8", "4", "3"] - correct order but with quotes. How could I modify it so that it returns [7,9,5,8,4,3]?
function digitize(n) {
var initialArray = (""+n).split('');
var reversedArray = [];
for (var i = initialArray.length - 1; i >= 0; i--) {
reversedArray[i] = initialArray.shift();
}
return reversedArray;
}
"One-line" solution:
var num = 348597,
arr = String(num).split("").reverse().map(Number);
console.log(arr); // [7, 9, 5, 8, 4, 3]
String(num) : The String global object acts as a constructor for strings and "converts" the given number into string(in this case)
The Array.reverse(): method reverses an array in place
The Array.map(): method creates and returns a new array calling a provided function on every array element
add parseInt to convert from string to number, since when you split you turn every integer into a string
function digitize(n) {
var initialArray = (""+n).split('');
var reversedArray = [];
for (var i = initialArray.length - 1; i >= 0; i--) {
reversedArray[i] = parseInt(initialArray.shift(),10);
}
return reversedArray;
}
console.log(digitize(348597));
Even better, reduce it to two lines:
function digitize(num) {
return num.toString().split('').reverse().map(Number);
}
The final map call applies a function to each element in the array (in this case the function converts a string to an object) - everything else simply converts the number to a string, splits the string to an array and reverses it.
Traditionally, parseInt would be used in the map call, but this gives rise to strange behaviour.
Just split and reverse
var num = 348597,
arr = num.toString().split("").reverse().map(Number);
document.write('<pre>' + JSON.stringify(arr, 0, 4) + '</pre>');
It is a simplified version of many other solutions that you can see, to deep understand how it works.
function digitize(n) {
let correctArr = [];
let arrOfNumbers = n.toString().split('');
let arrOfNumbersLength = arrOfNumbers.length;
for (let i = 0; i < arrOfNumbersLength; i++) {
let x = arrOfNumbers.pop();
correctArr.push(+x);
}
return correctArr;
}
console.log(digitize(348597));
If you care about performance, here is the one.
var num = 348597;
var digits = num + '';
var result = [];
for (var i = 0, length = digits.length; i < length; i++) {
result[length - 1 - i] = +digits[i];
}
console.log(result);
For beginners who may want to see a clear format on how to solve this via plain English, this may help to understand it:
function reverseNumber(num){
num = num + '';
let reversedText = num.split('').reverse().join('');
let reversedNumber = parseInt(reversedText, 10);
console.log("reversed number: ", reversedNumber);
return reversedNumber;
}
console.log(reverseNumber(12345));
A simpler way to solve this is below.
function digitize(n) {
numbers = n.toString()//convert n to a string
arrayNum = numbers.split('') //split the string and make an array
arrayRev =arrayNum.reverse()//reverse the new array made.
newArr = arrayRev.map(Number) // The Number constructor contains constants and methods for working with numbers. Values of other types can be converted to numbers using the Number() function.
return newArr;
}
Refactored
function digitize(n) {
return n.toString().split('').reverse().map(Number)
}
This is probably a really basic question, but either there is no answer on the web or I'm not using the correct terminology. I want to store two separate variables (A and B) into 1 master variable, so that master = A then B.
So if A = 3, B = 8, master would equal 38. Anyone know how to do this in JavaScript? I'm not a programmer but here is my attempt.
var A = 1;
var B = 5;
var master = A, B;
document.write(master);
You seem to be requesting string concatenation. If you want an array, use one of the other answers. Otherwise: var master = A.toString() + B.toString(); See this JSFiddle.
Use an array:
var A = 1,
B = 5;
var master = [A, B];
master[0]; // 1
master[1]; // 5
Both objects and arrays are OK, as has been suggested. I'll just throw in another suggestion - an encapsulation ;)
function Master(a, b) {
this.first = a;
this.second = b;
this.both = function() {
return a + '' + b;
}
}
And to use it
var a = 3;
var b = 8;
var m = new Master(a, b);
alert(m.first); // 3
alert(m.second); // 8
alert(m.both()); // 38 (mind the parentheses, this is a function call!)
I know you said you're new, so I probably shouldn't being throwing arrays on you. However, for the others...
If you plan to get more dynamic than a few variables, you might want to invest in arrays.Put them into an array, then loop through the array printing them out as a string into a variable.
var myArray = new Array();
myArray.push(3);
myArray.push(8);
var myString = "";
for(var a = 0; a < myArray.length; a++)
{
myString += myArray[a].toString();
}
let 1st_new = [ [ 123, 'jack', 'white', 'tehran' ];
let 2nd_new= [ 456, 'roz', 'black', 'theran' ] ];
let 1st_list.push("1");
let 2st_list.push("2");
console.log(1st_new);
console.log(2nd_new);
#or you could make vairables of thge lists and put it inside a "var master" and print that out.
This is my code, acting upon myArray:
var myArray = [];
var i;
for(i = 0; i < 20; i += 1) {
myArray.push(Math.random());
}
Is there a functional equivalent of the above that does without the dummy variable i?
Favorite answers:
while(myArray.push(Math.random()) < 20);
$.map(Array(20), Math.random);
for(var myArray = []; myArray.push(Math.random()) < 20;);
Not in ES5, there's no real functional equivalent to it, as you have to have something which has an amount of 20 to apply map to...
var my20ElementArray = [0,1,2,3,4,5,6,7,8,9,10];
var myArray = my20ElementArray.map(Math.random);
You could create an xrange-like function what is in Python but that would just hide this "unused" variable inside a function.
With JavaScript 1.7, you can use Array comprehensions for this task:
var myArray = [Math.random() for each (i in range(0, 20))];
However, with ES5.1 you can just use the Array constructor to generate an array of arbitrary length, and then map it to random numbers. Only drawback is that map() does not work with uninitialised values, so I first generate an Array of empty strings by using join and split:
var myArray = new Array(20).join(" ").split(" ").map(Math.random);
Ugly, but short. A maybe better (but less understandable) idea from Creating range in JavaScript - strange syntax:
var myArray = Array.apply(null, {length: 20}).map(Math.random);
Starting with #FelixKlings comment, one could also use this one-liner without the i loop variable:
for (var myArray=[]; myArray.push(Math.random()) < 20;);
// much better:
for (var myArray=[]; myArray.length < 20;) myArray.push(Math.random());
Are you looking for something as follows:
function makeArray(length, def) {
var array = [];
var funct = typeof def === "function";
while (array.push(funct ? def() : def) < length);
return array;
}
Then you can create arrays as follows:
var array = makeArray(100); // an array of 100 elements
var zero = makeArray(5, 0); // an array of 5 `0`s
In your case you may do something like:
var myArray = makeArray(20, Math.random);
See the following fiddle: http://jsfiddle.net/WxtkF/3/
how about this?
it's functionale style and it's very concise.
var makeRandomArray = function(n){
if (n == 0) return [];
return [Math.random()].concat(makeRandomArray(n-1));
};
console.log(makeRandomArray(20))
http://jsfiddle.net/YQqGP/
You could try:
var myArray = String(Array(20)).split(',')
.map( () => Math.random() );
Or extend the Array prototype with something like:
Array.prototype.vector = function(n,fn){
fn = fn || function(){return '0';};
while (n--){
this.push(fn());
}
return this;
}
// usage
var myArray = [].vector(20, () => Math.random());
Or try something funny:
var myArray = function a(n,fn){
return n ? a(n-1,fn).concat(fn()) : [];
}(20, () => Math.random())
Or use Array.from (ES>=2015)
Array.from({length: 20}).map(() => Math.random())
>>> def clockwise(r):
... return list(r[0]) + clockwise(list(reversed(zip(*r[1:])))) if r else []
...
>>> a = [
... [ 1, 2, 3],
... [ 5, 6, 7],
... [ 9, 10, 11]]
>>> clockwise(a)
[1, 2, 3, 7, 11, 10, 9, 5, 6]
I'm trying to change the function clockwise into Javascript but can't seem to get it to work.
I've created some methods with similar functions:
function zip(masterArray){//zips 2 arrays
var innerLoop = masterArray.length; //inner loop
var outerLoop = 0;
//get length of shortest
for (var i = 0; i<masterArray.length;i++){
var a = masterArray[i].length;
if (outerLoop==0){outerLoop = a;}else if(a < outerLoop){outerLoop = a;}
}
var newOuterArray = new Array(outerLoop);
for (var x = 0; x<outerLoop;x++){
var newInnerArray = new Array(innerLoop);
for (var y = 0; y<innerLoop;y++){
newInnerArray[y] = masterArray[y][x];
}
newOuterArray[x] = newInnerArray;
}
return newOuterArray;
}
function reversed(arr){
var newArray = new Array(arr.length);
var n = 0;
for(var i=arr.length-1; i>=0; i--){
newArray[n++] = arr[i];
}
return newArray;
}
function clockwise(r){
if(r.length>0){
var a = reversed(zip(r.slice(1)));
a.splice(0,0,r[0]);
return clockwise(a);
}else{
return [];
}
}
Here's my progress. I'm stuck at the last part: clockwise error in firebug is too much recursion.
I think the problem lies in the use of splice. Try something like this instead...
function clockwise(r){
if(r.length>0){
var remaining = r.slice(1)
var a = reversed(zip(remaining));
return r[0].concat(clockwise(a));
} else {
return [];
}
}
I think you want the recursive call to clockwise() to be before you prepend r[0] otherwise you never get down to an empty string.
I don't follow what the algorithm is trying to do, but the Javascript version of clockwise looks like it can only ever return []. There are two return paths. One calls clockwise, the other returns [] so the only way out of that function is to return []. That's not how your python version works.
I haven't looked at reversed and zip, but there is a logic difference in the javascript version of clockwise. In the javascript version, you remove the first item in the array, then reverse and zip, then put the first item back on the array and call clockwise on the whole thing. In the Python version, you remvoe the first item in the array, call clocks and reverse on only the item without the first version, then add the first one back on afterwards. Very different logic. The Python version is much more likely to end.
I haven't looked at the other functions reverse and zip, but this looks like a more faithful javascript version of clockwise:
function clockwise(r) {
if (r.length > 0) {
var a = clockwise(reversed(zip(r.slice(1)))); // call clockwise on array starting at index 1
a.splice(0,0,r[0]); // put first value in original array back onto the beginning of the result
return (a); // return new array
} else {
return [];
}
}