Weird behaviour in Array.fill [duplicate] - javascript

This question already has answers here:
Array.fill(Array) creates copies by references not by value [duplicate]
(3 answers)
Closed 4 years ago.
When i use Array.fill to fill a multidimensional array, i get a weird behaviour when pushing to one of the arrays:
var arr = Array(2).fill([]);
arr[0].push(5);
console.log(arr);
//=> prints [[5], [5]]

fill is essentially doing this:
var content = [];
for (var i = 0; i < 2; i += 1) {
arr[i] = content;
}
So, your array will have a reference to the array you've passed to fill in each property.

It sounds weird, but what your code actually does is create an array ([]) and put a reference for that array in each of the items of the Array(2). So whenever you change that reference - every array that is referenced to that Array is changed.
It's exactly the same as:
var a = [];
var arr = Array(2).fill(a);
a.push(5);
console.log(arr[0][0], arr[1][0]);
a[0] = 2;
console.log(arr[0][0], arr[1][0]);
You can see that the values inside the arr are affected by the change to the a array.

Related

Javascript Grammer: how to assign correct values to an array of objects [duplicate]

This question already has answers here:
new Array(_).fill(object) does not create new instances of object [duplicate]
(5 answers)
Array.prototype.fill() with object passes reference and not new instance
(7 answers)
Closed 2 years ago.
let's look at the code:
Test() {
let array1 = new Array(5).fill({ a: 0 })
let array2 = new Array(5).fill({ a: 0 })
for (let i = 0; i < 5; i++) {
setTimeout(() => {
array1[i].a = i
array2[i] = {a:i}
console.warn("array = ", array1)
console.warn("array2 = ", array2)
}, 0.2 * i)
}
}
In this case, I wanna assign a series of values to the array1 & array2, and there are two ways to do it, which lead to totally different results.
In the case array1[i].a = i, after all the code is ran, the result is array = [{a:4},{a:4},{a:4},{a:4},{a:4}], which is not what i wanted.
In the second case array2[i] = {a:i}, the result will be [{a:0},{a:1},{a:2},{a:3},{a:4}] as expected.
I wanna know why is it like this? What's the machanics behind this phenomenon?
Thank you.
When you call .fill() and pass an object, you assign the exact same object to every element of the array. Thus, modifying a property at one array index modifies the same property at all the other indexes, because they're all pointing to the same thing.
There are a variety of ways around this issue. You could fill the array with 0 or null or some dummy value and then iterate through with .forEach(), or more simply just use an indexed for loop to initialize each element. If you initialize with { a: 0} in a for loop, a new object will be created on each iteration.

Array value assignment not working as expected Javascript [duplicate]

This question already has answers here:
Array.fill(Array) creates copies by references not by value [duplicate]
(3 answers)
Closed 2 years ago.
The code I'm working on right now requires me to assign a value to a single cell in a 2-D array.
But the assignment doesn't seem to work out as expected.
let b = new Array(3).fill(new Array(3).fill(0));
b[1][1] = 1;
console.log(b.toString());
I just can't really understand why it produces this output.
The below code gives me the output I expect but I would really prefer being able to do it in a manner that resembles the first snippet.
let b = []
for(let i = 0; i < 3; i++){
b.push([])
for(let j = 0; j < 3; j++){
b[i].push(0)
}
}
b[1][1] = 1
console.log(b.toString())
You can avoid assigning the same array reference by using the built in mapping callback of Array.from()
let b = Array.from({length:3}, (_,i) => Array(3).fill(i));
console.log(b)
In your first example, it creates one array, then fills every element to that one array. This means that a change in one will be reflected in everything else. If you want to construct a new array for each element, then you could try mapping it:
let b = new Array(3).fill(null).map(_ => new Array(3).fill(0));
b[1][1] = 1;
console.log(b.toString());

JavaScript matrix wired behaviour when using new Array() [duplicate]

This question already has answers here:
Array.fill(Array) creates copies by references not by value [duplicate]
(3 answers)
Closed 4 years ago.
When i use Array.fill to fill a multidimensional array, i get a weird behaviour when pushing to one of the arrays:
var arr = Array(2).fill([]);
arr[0].push(5);
console.log(arr);
//=> prints [[5], [5]]
fill is essentially doing this:
var content = [];
for (var i = 0; i < 2; i += 1) {
arr[i] = content;
}
So, your array will have a reference to the array you've passed to fill in each property.
It sounds weird, but what your code actually does is create an array ([]) and put a reference for that array in each of the items of the Array(2). So whenever you change that reference - every array that is referenced to that Array is changed.
It's exactly the same as:
var a = [];
var arr = Array(2).fill(a);
a.push(5);
console.log(arr[0][0], arr[1][0]);
a[0] = 2;
console.log(arr[0][0], arr[1][0]);
You can see that the values inside the arr are affected by the change to the a array.

how to create array object using integer variable javascript [duplicate]

This question already has answers here:
How to use a variable for a key in a JavaScript object literal?
(16 answers)
Closed 7 years ago.
I need to fill an array object as like below using integer variable.
for(i=1; i<=2; i++)
arr[i].push({i:(100 * i)})
Expected result is:
arr = [{ 1:100,2:200},{1:100,2:200}]
Problem is, array created as like below
arr = [{i:100,i:200},{i:100,i:200}]
You need to push to arr instead of arr[i].
Also, you can't use a variable as a key in json directly.
var arr = [];
for(i=1; i<=2; i++)
{
var b = {};
b[i] = 100*i;
arr.push({[i]:(i*100)});
}
console.log(arr);

Dynamically create js Array filled with certain value [duplicate]

This question already has answers here:
Create an array with same element repeated multiple times
(25 answers)
Closed 7 years ago.
I'm wondering if there is a way to create javascript/jquery array in one-liner to receive something like:
my_array = ['-', '-', ,'-' ,'-']
Idea is that array should be created with dynamic length and all values filled with given value.
Thanks in advance!
Try:
var total = 4;
var my_array = new Array(total + 1).join("-").split("");
document.write(JSON.stringify(my_array))
.fill Support The native function will be added in (ECMAScript 6), but for now is not available.
if(!Array.prototype.fill){
Array.prototype.fill = function(val){
for (var i = 0; i < this.length; i++){
this[i] = val
}
return this
}
}
var my_array = new Array(4).fill("-"); //returns ["-","-","-","-"]
Try to use:
Array.apply(null, new Array(63)).map(String.prototype.valueOf,"-")

Categories

Resources