Array.Fill(Array) Creates Copies by References Not by Value

Array.fill(Array) creates copies by references not by value

You could use Array.from() instead:

Thanks to Pranav C Balan in the comments for the suggestion on further improving this.

let m = Array.from({length: 6}, e => Array(12).fill(0));
m[0][0] = 1;console.log(m[0][0]); // Expecting 1console.log(m[0][1]); // Expecting 0console.log(m[1][0]); // Expecting 0

Why does Array(n).fill([]) not the same as hardcoding the array or using a for loop to create that array?

as described here

the fill method of Array fills the array (or a given range of indices in the array) with the same value

that means when you write the line Array(3).fill([]) it actually puts the same array created using [] in all the indices of the array, so editing the array in one place, affects all indices (since they all point to the same array [])

Array.prototype.fill() with object passes reference and not new instance

You can first fill the array with any value (e.g. undefined), and then you will be able to use map:

var arr = new Array(2).fill().map(u => ({}));
var arr = new Array(2).fill().map(Object);

JavaScript - why Array.prototype.fill actually fills a pointer of object when filling anything like 'new Object()'

I am wondering why it's happening?

Array#fill takes the value you give it as the first argument, and fills the array with copies of that value.

The value you're giving it is a reference to an array, so naturally what it gives you back is an array filled with copies of that reference. Not copies of the array, copies of the reference.

E.g., it behaves this way for exactly the same reason this code:

var a = new Array(10);
var b = a;

...leaves us with a and b both referring to the same array (both containing the same value; a reference to the single array we've created).

Let's throw some Unicode-art at it:

After this code runs:

var a = new Array(10);
var b = a;

we have this in memory (minus a few irrelevant details):


a:Ref89895−−−+
|
| +−−−−−−−−−−−−−−−+
+−−−−−>| array |
| +−−−−−−−−−−−−−−−+
| | length: 10 |
b:Ref89895−−−+ +−−−−−−−−−−−−−−−+

a and b contain a reference, which I've shown here as Ref89895 although we never see the actual value. That's what's copied by b = a, not the array itself.

Similarly, when you do:

var matrix = new Array(10).fill(new Array(10), 0);

you end up with


+−−−−−−−−−−−−−−−+
matrix:Ref89895−−−>| array |
+−−−−−−−−−−−−−−−+
| length: 10 |
| 0: Ref55462 |--\
| 1: Ref55462 |--\\
| 2: Ref55462 |--\\\
| 3: Ref55462 |--\\\\ +−−−−−−−−−−−−−−−+
| 4: Ref55462 |---+++++->| array |
| 5: Ref55462 |--///// +−−−−−−−−−−−−−−−+
| 6: Ref55462 |--//// | length: 10 |
| 7: Ref55462 |--/// +−−−−−−−−−−−−−−−+
| 8: Ref55462 |--//
| 9: Ref55462 |--/
+−−−−−−−−−−−−−−−+

To create a 10-place array where each of the 10 places is itself a 10-place array of 0, I'd probably use either Array.from or fill with map:

// Array.from
var matrix = Array.from({length: 10}, function() {
return new Array(10).fill(0);
});

// fill and map
var matrix = new Array(10).fill().map(function() {
return new Array(10).fill(0);
});

or in ES2015:

// Array.from
let matrix = Array.from({length: 10}, () => new Array(10).fill(0));

// fill and map
let matrix = new Array(10).fill().map(() => new Array(10).fill(0));

What am I missing in this Javascript Array behavior?

function na(){
return Array(2).fill(Array(2))
}

na() fills the empty Array(2) with shallow copies of the second Array(2) object.

As a result changing values in any of the clones changes the Array's value everywhere.

a = Array(5).fill(Array(3))

a[0][0] = 1
a[0][1] = 2
a[0][2] = 3

console.log(JSON.stringify(a))

javascript use Array fill() function to init a 2D array

That happens because dp.fill() is using a reference to the same array, defined by new Array(n).fill(false). When you change dp[0], you also "change" dp[1], dp[2], etc...

So you should use the code you posted below.

How do I fill a new array with n distinct empty arrays, in a concise one-line initialization statement?

Try:

let radix = 10;
let bucket = [...Array(radix)].map(e=>[])
bucket[0].push(1)
console.log(JSON.stringify(bucket));

Creating 2D arrays using new Array in Javascript

Because .fill() takes the argument and, if it's an object, it copies the reference to that object into every index of the new array. Since in fact [] is an object, your new array ends up being filled with references to the same array.

From the docs:

If the first parameter is an object, it will copy its reference and fill the array with references to that object.



Related Topics



Leave a reply



Submit