0

I need to create an array of arrays. Every nested array should be filled with zeroes. I'v tried this:

let test = Array
  .from(
    new Array(8)
      .fill(
        new Array(8).fill(0)
      )
  );

But then I'd got issue with a reference. For example if I do this:
test[1][2] = 1;
then every nested array has value 1 at index 2:
console.log(test[2][2]) // 1

I came up with simple solution using a loop:

const testArray = new Array(8);

for (let i = 0; i < testArray.length; i++) {
  testArray[i] = new Array(8).fill(0);
}

Now it works and there's no issue with reference. But I don't understand why this issue occurred in the first try. Can someone be so kind and explain that to me?

0

2 Answers 2

3

You're filling the array with 8 identical references to a single array, rather than 8 distinct references to 8 separate arrays. fill reuses the same value for each entry in the array it fills, so you get this:

+−−−−−−−−−−−−+
|  (array)   |
+−−−−−−−−−−−−+                           +−−−−−−−−−+
| 0: Ref2215 |−−−−−−−−+−+−+−+−+−+−+−−−−−>| (array) |
| 1: Ref2215 |−−−−−−−/ / / / / / /       +−−−−−−−−−+
| 2: Ref2215 |−−−−−−−−/ / / / / /        | 0: 0    |
| 3: Ref2215 |−−−−−−−−−/ / / / /         | 1: 0    |
| 4: Ref2215 |−−−−−−−−−−/ / / /          | 2: 0    |
| 5: Ref2215 |−−−−−−−−−−−/ / /           | ...     |
| 6: Ref2215 |−−−−−−−−−−−−/ /            +−−−−−−−−−+
| 7: Ref2215 |−−−−−−−−−−−−−+
+−−−−−−−−−−−−+

It doesn't matter which array slot you use, they all contain a reference to the same one array.

Your second code block creates separate arrays (I won't bother with the diagram :-)). Here's a slightly shorter way to do it:

let test = Array.from(
                Array(8),
                () => new Array(8).fill(0) // Mapping callback creates
           );                              // new array for every entry
                                           // in the outer array
Sign up to request clarification or add additional context in comments.

6 Comments

That`s it. I've just found this on MDN docs: "When the fill method gets passed an object, it will copy the passed object, and fill the array with a reference to the copy". Thanks you.
@MateuszWitkowski: Yikes, we should fix that then. fill absolutely does not "copy the object."
How did you create that graph so swiftly?
I'm tolerably quick with vim.
Thanks @T.J.Crowder I'm sorry that this question was marked as duplicate (I won't bother to argue against it). Especially that IMO your answer is more verbose and informative than the answers in the question that I supposedly duplicated.
|
1

The reason is that the second new Array(8).fill(0) is referenced by all the cell of the parent Array(). You are creating it only once!

Instead, in your second try, you are creating it 8 times.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.