This question already has answers here:
Setting one value in 3D array mutates others values
(2 answers)
Closed 4 years ago.
I'm struggling with a weird Array.prototype.fill behaviour:
const arr = new Array(5)
.fill([]);
arr[0].push('element pushed to 0 only');
console.log(arr[1]); // ['element pushed to 0 only']
All of the items inside the array are filled with this string. I assume all of the [] array-s are pointing to the same array, but I don't see why, could anyone explain?
In fill([]), the argument [] is evaluated before the call to fill.
It's the same as
const subarray = [];
const arr = new Array(5);
arr.fill(subarray);
which is the same as
const subarray = [];
const arr = new Array(5);
for (var i=0; i<arr.length; i++) arr[i] = subarray;
In other words you have the same sub array at all indices: arr[1] is arr[0].
If you want to have different subarrays, you coul do
const arr = Array.from({length:5}, ()=>[]);
Related
This question already has answers here:
Array.fill(Array) creates copies by references not by value [duplicate]
(3 answers)
Closed 8 months ago.
I was trying to get an array with some arrays inside of it, and each of those inner arrays should contain ONE of the n powers of 2, not all.
let n = 5;
let arr = Array(n + 1).fill([]);
const transform = function (el, i) {
el.push(2 ** i);
};
console.log(arr); // [Array(0), Array(0), Array(0), Array(0), Array(0), Array(0)]
arr.map(transform);
console.log(arr); //[Array(6), Array(6), Array(6), Array(6), Array(6), Array(6)]
//was expecting //[[1], [2], [4], [8], [16], [32]]
Fill is just setting every index with a reference to that array. It is not creating a new array in every index.
The easiest way to create an array and fill it with empty arrays is with Array.from
const n = 5;
const transform = (arr, index) => arr.push(2 ** index);
const myArray = Array.from({length: n}, () => []);
myArray.forEach(transform);
console.log(myArray);
When using fill, they share the same instance. So changing one changes all the others. You need to use map after filling
new Array(6).fill(null).map(() => []).map(transform)
It may be easier to use a traditional for loop to accomplish your end result. Using map and transform is a more roundabout way of doing the following:
let n = 5;
let arr = [];
for (let i = 0; i <= n; i++) {
arr.push([2**i]);
}
console.log(arr);
This question already has answers here:
How to create a 2d array of zeroes in javascript?
(5 answers)
Changing one array element affects other elements
(1 answer)
Closed 1 year ago.
I just found something is interesting in Javascript multidimensional array.
let arr = Array(3).fill([]);
arr[0].push('1');
I thought the result should be arr = [['1'], [], []], but got arr = [['1'], ['1'], ['1']].
If update a value as arr[2][0] = '*', expected array to be arr = [['1'], ['1'], ['*']], but got arr = [['*'], ['*'], ['*']].
So why Javascript multidimensional array work like this? How to just update a value in multidimensional array?
From pichard's comment, I got the right result by doing as following:
let arr = Array(3).fill([]).map(obj => { return [] });
arr[0].push('1');
arr[2][0] = '*';
The result is arr = [['1'], [], ['*']]
This question already has answers here:
Zip arrays in JavaScript?
(5 answers)
Closed 3 years ago.
I wanted to merge two arrays like you can fold 2 packs of cards - in ugly code with for loop and assuming same length so no if's for safety it would look like this:
const arr = [1,2,3];
const rra = [4,5,6];
const result = [];
for(let i=0; i<arr.length; i++){
result.push(arr[i],rra[i]);
}
console.log(result); // Array(6) [ 1, 4, 2, 5, 3, 6 ]
I know there is something similar in String.raw() but it cuts off last element and returns a string, is there equivalent in array ?
String.raw({raw: [1,2,3]}, ...[4,5,6]); //"14253"
You can use .flatMap() for this - This is the same as .map(), followed by .flat()
const arr = [1,2,3];
const rra = [4,5,6];
let newArray = arr.flatMap((ele, i) => [ele, rra[i]]);
console.log(newArray);
This question already has answers here:
Most efficient way to create a zero filled JavaScript array?
(45 answers)
Closed 4 years ago.
Hello I want to init Array with 5 zero elements in JS. Without classic initiation var arr = [0, 0, 0, 0, 0]
I try some variant:
var arr = new Array(5).map(() => 0);
var arr = new Array(5).map(function () {return 0;});
var arr = Array(5).map(function () {return 0;});
but this examples are not working.
Either use .fill:
const arr = new Array(5).fill(0);
console.log(arr);
or Array.from, which has a built-in map function you can pass as a second parameter:
const arr = Array.from({ length: 5 }, () => 0);
console.log(arr);
See MDN:
map calls a provided callback function once for each element in an array, in order, and constructs a new array from the results. callback is invoked only for indexes of the array which have assigned values, including undefined. It is not called for missing elements of the array (that is, indexes that have never been set, which have been deleted or which have never been assigned a value).
Using Array.from as above assigns undefined values to each element of the array, whereas new Array does not, which is why you can map after Array.from but not after invoking the Array constructor.
You need use method fill for array's in initialization.
example:
var arr = new Array(5).fill(0);
May a for loop help you?
For(i=0; i<N; i++){
array[i]=value;
}
For a 5 length array of 0 it becomes
for(i=0; i<5; i++){
array[i]=0;
}
This question already has answers here:
How to merge two arrays in JavaScript and de-duplicate items
(89 answers)
Closed 9 years ago.
I am tying to merge two arrays in JS, and then sort them. The following code will output the two arrays on the page, but ONLY if I remove the "newArr.sort();" line. Otherwise, I get nothing. Can anyone help a newbie here?
function merge(arr1, arr2){
var arr1 = [1,21,13,24,15];
var arr2 = [16,7,81,59,14];
var newArr = "[ ]";
arr1.sort();
arr2.sort();
newArr = arr1+","+arr2;
newArr.sort();
document.writeln(newArr);
}
var arr1 = [1,21,13,24,15];
var arr2 = [16,7,81,59,14];
var arr3 = arr1.concat(arr2);
alert(arr3);
Jsfiddle: http://jsfiddle.net/ZRLSs/