2

I'm initializing a 2x2 3D array in one line with 0's:

let matrix = new Array(2).fill(new Array(2).fill(0));

This results in

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

Doing matrix[0][0] = 1 results in:

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

What's going on here? Why are both of the 0-th indeces being set to 1?

mickl
  • 48,568
  • 9
  • 60
  • 89
xheyhenry
  • 1,049
  • 2
  • 13
  • 25
  • JS arrays are mutable. – user202729 Feb 02 '18 at 06:23
  • See [this](https://stackoverflow.com/questions/966225/how-can-i-create-a-two-dimensional-array-in-javascript#comment62282884_966225). – user202729 Feb 02 '18 at 06:24
  • 3
    `new Array(2).fill(0)` is only called once. Imagine what that means. Take your time... Hint: there are only 0 zeroes in this game. It is just another flavor of https://stackoverflow.com/questions/4220611/why-does-changing-one-array-alters-the-other – trincot Feb 02 '18 at 06:28
  • A solution in one line: `let matrix = Array.from({length:2},()=>new Array(2).fill(0))` – Patrick Roberts Feb 02 '18 at 06:34
  • Possible duplicate of [List of lists changes reflected across sublists unexpectedly](https://stackoverflow.com/questions/240178/list-of-lists-changes-reflected-across-sublists-unexpectedly) (although the link is python the reasoning is identical). – Nick is tired Feb 02 '18 at 07:29

2 Answers2

3

The fill() method fills all the elements of an array from a start index to an end index with a static value.

In your case let matrix = new Array(2).fill(new Array(2).fill(0));, the new Array(2).fill(0) is evaluated once, its reference is provided to all the outer array. So, every outer Array is referencing the same inner array. Therefore, modifying a value is updating all other value.

You need to create different a new array reference for each row. The below code is creating a new inner array for every index.

let matrix = Array.from({length: 2}, _ => new Array(2).fill(0));
console.log(matrix);
matrix[0][0] = 1;
console.log(matrix);
Hassan Imam
  • 21,956
  • 5
  • 41
  • 51
1

in your implementation, matrix is an array with two elements, and those two elements are the same object. consider another 2d array constructor that doesn't have this problem, such as this one.

function zeros(width, height){
    matrix = new Array(height);
    for(var i = 0; i < height; i++){
        matrix[i] = new Array(width).fill(0);
    }
    return matrix;
}

var matrix = zeros(2, 2);
console.log(matrix); //before changes
matrix[0][0]=1;
console.log(matrix); //after changes
Jigar Shah
  • 6,143
  • 2
  • 28
  • 41