1

Playing around with different ways of instantiating Arrays with Javascript and I noticed some interesting behavior:

matrix = Array(3).fill(Array(3).fill(0))

Creates an NxN matrix of 0 values

[
  [0,0,0],
  [0,0,0],
  [0,0,0]
]

I then tried changing the first row of the matrix to be all 1's:

matrix[0].fill(1)

Which for some reason turned ALL values in the matrix to 1's:

[
  [1,1,1],
  [1,1,1],
  [1,1,1]
]

This behavior doesn't make sense to me. Shouldn't only the first row be affected by the final call to Array.fill? What's going on here?

Ryan B
  • 166
  • 2
  • 13

1 Answers1

2

Your code is equivalent to

let row = [0,0,0]
let matrix = [row, row, row];
row.fill(1);

because .fill(Array(3).fill(0)) calls Array(3).fill(0) once to get the fill value - if the fill argument were a callback, then it would call it for each item in matrix - but the fill argument is a value

In javascript, arrays are said to be a reference

var a = [1,2,3], b=a;
b[0] = 4

will result in both a and b referencing an array with values [4,2,3]

so, since each row is the same array, your result is as you've seen

try this instead

const matrix = Array.from({length:3}, () => Array(3).fill(0))
matrix[0].fill(1);
console.log(matrix);

The above is equivalent to

const matrix = [Array(3).fill(0), Array(3).fill(0), Array(3).fill(0)];
matrix[0].fill(1);

Now each entry in matrix is a different Array, not the same one each time

Jaromanda X
  • 53,868
  • 5
  • 73
  • 87
  • I had a feeling it was something along the lines of this. Thanks for the thorough explanation! – Ryan B Feb 28 '20 at 12:04