2

I'm trying to create a 0 initialized 2d array. I have two tests that should be identical, but they are not. Any modification to test1[x] will result in all test1[x] entries to match. Why are all sub-arrays of test1 the same?

Note: Running this on codepen, all sub-arrays after the first say [circular object Arrray]

Link to codepen: https://codepen.io/tannyr/pen/qXLmeG?editors=1111

var test1 = Array(2).fill(Array(2).fill(0))

var test2 = [[0,0],[0,0]]

test1[0][0] = 1  // <= Should edit a single value
test2[0][0] = 1

console.log(test1[0], test1[1])  // [1, 0] [1, 0]  <= Should match test 2
console.log(test2[0], test2[1])  // [1, 0] [0, 0]
Dij
  • 9,761
  • 4
  • 18
  • 35
Tannyr
  • 21
  • 4

3 Answers3

2

This happens because you are adding reference of same array to both the elements in test1. var test1 = Array(2).fill(Array(2).fill(0)) is essentially same as

var arr = Array(2).fill(0);
var test1 = Array(2).fill(arr);

since both elements have reference to same array, if you edit one changes are reflected in other as well. whereas in var test2 = [[0,0],[0,0]] you are adding two separate arrays to both elements of test2 and so you can edit both separately.

you can also use a loop to fill the elements of array, something like this:

var test1 = [];
for(var i=0; i<2; i++)
   test1.push([0,0]);
Dij
  • 9,761
  • 4
  • 18
  • 35
1

It's a bit tricky, but when you use fill in that way, it makes one Array and then puts it into all the fill positions. The way you can do what you want is to say Array(2).fill().map(() => [0, 0])

This will initialize all the slots in the array, then map the value you need into the new slots.

DillGromble
  • 383
  • 2
  • 8
  • note that lamda would not work on all browsers. Just in case you were using this for client side js. – Neville Nazerane Aug 31 '17 at 02:26
  • `Array(2).fill().map(() => [0, 0])` How is fill working without parameters? What is it doing in this example? – Tannyr Aug 31 '17 at 03:19
  • Since fill doesn't have a parameter it returns undefined. This works because using Array(2) doesn't actually make any space for things to go in the array, it only sets the .length property. When you use fill, it fills the array with undefined, which then allows map to traverse the array and insert new values. – DillGromble Aug 31 '17 at 03:32
  • That is super helpful to know. Thank you! – Tannyr Sep 01 '17 at 00:13
0

Array(2).fill(0) creates an Array and the outter Array(2).fill seems to add the exact created array twice. Which means both the items in your test1 array reference to the same array. So if you change the values of one of the elements of one array, considering that both arrays point to the same location, it changes the element in both arrays. Remember the order in which it would work. You are calling a function and passing on a value. It would evaluate the inner function only once, get its return type and use it inside the outer function.

Neville Nazerane
  • 6,622
  • 3
  • 46
  • 79