0

The following code should create an empty array that contains 7 empty arrays, effectively a 7x7 grid.

Accessing elements in nested arrays works fine, but trying to change their values changes the value of all elements in the same column (so changing [1][1] also changes [0][1], [2][1] etc.). I can't understand why.

var usage = new Array(7).fill(new Array(7).fill(0));

usage[1][1] += 1;

https://jsfiddle.net/v3o4rwsz/

user3356802
  • 141
  • 2
  • 8
  • Does this answer your question? [Array.prototype.fill() with object passes reference and not new instance](https://stackoverflow.com/questions/35578478/array-prototype-fill-with-object-passes-reference-and-not-new-instance) – Ivar Mar 31 '22 at 11:51

3 Answers3

0

This is an easy trap to fall into. Your code is equivalent to:

var innerArray = [0,0,0,0,0,0,0]; // .fill(0)
var usage = [innerArray, innerArray, innerArray, innerArray,
             innerArray, innerArray, innerArray]; // .fill(innerArray)

console.log(usage[0]==innerArray); // true
console.log(usage[1]==innerArray); // true

To get the result you want, you need to create a new array for each element in usage, e.g:

var usage = [];
for (var i=0; i<7; i++) {
    usage.push(new Array(7).fill(0));
}
Chas Brown
  • 386
  • 1
  • 10
0

The contents of the first fill is only evaluating once - creating the second array, and then it is duplicating that array 7 times, so they are all connected.

It is the equivalent to:

var t1 = new Array(7).fill(0);

var t2 = t1;
var t3 = t1;
var t4 = t1;
var t5 = t1;
var t6 = t1;
var t7 = t1;

t2[3] = "duplicate"

console.log(t1);
console.log(t2);
console.log(t3);

Which will show the same value in t1 to t7.

K Scandrett
  • 16,390
  • 4
  • 40
  • 65
0

I believe this behaviour is caused by your use of .fill(). If you look at the definition of that function here you'll see it populates an array with a static value

This means that when you reference usage[1][1] you are referencing the same array that exists in usage[0][1], usage[2][1] and so on.

You can populate the array with a for loop, like below.

var usage2 = new Array();

for(var i=0;i<7;i++) { 
    usage2.push(new Array(7).fill(0));
}

Now when you check your values you'll see the expected result where only one array is altered, like in the below screenshot from my Chrome console.

JS Console Screenshot

James
  • 903
  • 7
  • 22