1

I am trying to create a generative object, filled with arrays (all 0).

//declaration of the data object
var data = {}

//initiate to fill data with keys and arrays
function init()
{
 var pos = Array.apply(null,Array(16)).map(Number.prototype.valueOf,0); //creates empty array filled with 0
 for(var i = 0; i < 16; i++) {
  data[i] = pos;
 }
}

init();

console.log(data);

This would give me a data filled with keys from 0 to 2 and each key has an array filled with 0;

{
  '0': [
    0, 0, 0, 0, 0, 0,
    0, 0, 0, 0, 0, 0,
    0, 0, 0, 0
  ],
  '1': [
    0, 0, 0, 0, 0, 0,
    0, 0, 0, 0, 0, 0,
    0, 0, 0, 0
  ],
  '2': [
    0, 0, 0, 0, 0, 0,
    0, 0, 0, 0, 0, 0,
    0, 0, 0, 0
  ]
}

Now, when I try to modify a specific array like this:

data[0][1] = 1;

then the result will print that all arrays in all keys have been modified...

{
  '0': [
    0, 1, 0, 0, 0, 0,
    0, 0, 0, 0, 0, 0,
    0, 0, 0, 0
  ],
  '1': [
    0, 1, 0, 0, 0, 0,
    0, 0, 0, 0, 0, 0,
    0, 0, 0, 0
  ],
  '2': [
    0, 1, 0, 0, 0, 0,
    0, 0, 0, 0, 0, 0,
    0, 0, 0, 0
  ]
}

This makes no sense to me because I wanted to modify only the first array with key 0... If I create the whole object manually, the change will work fine, but if I do it this way (generative), I get this strange bug. Any ideas?

HardGroove
  • 11
  • 1
  • because `pos` is always the same array, if you create it inside the for loop `data[i] = Array.apply(null,Array(16)).map(Number.prototype.valueOf,0);` then `data[0][1] = 1;` will only affect the first row – GrafiCode Aug 28 '22 at 11:44
  • You could try: `data[i] = [...pos];`, taking advantage of the spread operator within an Array literal to create a new Array from the created `pos` Array (which solves the problem, but the question was "*why..?*", which has already been answered below). – David Thomas Aug 28 '22 at 11:47

1 Answers1

1

It is because every key in data is referencing to the same array. Array is an object. When you assing object to some variable, or pass it as argument, you just pass it refference.

To make your code to work correctly as you like, you have to generate new array every time, you want to assign it to some key in data.

const data = {};

for (let i = 0; i < 16; i++) {
  data[i] = new Array(16).fill(0);
}
Profesor08
  • 1,181
  • 1
  • 13
  • 20
  • This is an **often**-repeated duplicate question. – T.J. Crowder Aug 28 '22 at 11:51
  • You are right, I haven't thought about it, once I added a new array into the loop. All worked at suppose to. Many thanks. p.s. I do not use fill, because I work in ES5 environment (This code is not used in a web browser) – HardGroove Aug 28 '22 at 11:52