37

I'm trying to create a 6 by 12 Matrix using Array.fill

let m = Array(6).fill(Array(12).fill(0));

While this works, the problem is that the inner Arrays are actually all referencing the same Array object.

let m = Array(6).fill(Array(12).fill(0));
m[0][0] = 1;
console.log(m[1][0]); // Outputs 1 instead of 0

I wanted (and expected) the value of m[1][0] to be 0.

How can I force Array.fill fill copy-by-values of the given argument (eg: Array(12).fill(0) is the argument in my case) instead of copying by reference ?

Pranav C Balan
  • 113,687
  • 23
  • 165
  • 188
XCS
  • 27,244
  • 26
  • 101
  • 151
  • 3
    You can't force `Array.fill()` to do anything other than what it already does. You can write your own function to do it of course. – Pointy Jun 21 '16 at 16:28
  • @Pointy You are right, a second parameter to fill for "deep-copy" would be useful :) – XCS Jun 21 '16 at 16:33
  • 1
    It might be nice to be able to pass a generator function of some sort. – Rose Kunkel Jun 21 '16 at 16:35
  • Use lodashes deep clone and it will remove the references – Ben Hare Jun 21 '16 at 17:10
  • @WilliamKunkel: In most use cases, you could simply do `Array.from(generator)` instead of something like `Array(6).fillBy(generator, 0, 6)` – Bergi Jun 21 '16 at 17:11

3 Answers3

32

You could use Array.from() instead:

Thanks to Pranav C Balan in the comments for the suggestion on further improving this.

let m = Array.from({length: 6}, e => Array(12).fill(0));

m[0][0] = 1;
console.log(m[0][0]); // Expecting 1
console.log(m[0][1]); // Expecting 0
console.log(m[1][0]); // Expecting 0

Original Statement (Better optimized above):

let m = Array.from({length: 6}, e => Array.from({length: 12}, e => 0));
KevBot
  • 17,900
  • 5
  • 50
  • 68
8

You can't do it with .fill(), but you can use .map():

let m = new Array(6).map(function() { return new Array(12); });

edit oh wait that won't work; .map() won't iterate through the uninitialized elements. You could fill it first:

let m = new Array(6).fill(null).map(function() { return new Array(12); });
Pointy
  • 405,095
  • 59
  • 585
  • 614
1

You can't do it with Array#fill method. Instead iterate over the array and add newly created array using a for loop.

let m = Array(6);
for (var i = 0; i < m.length; i++)
  m[i] = Array(12).fill(0)

m[0][0] = 1;
console.log(m[1][0]);
Pranav C Balan
  • 113,687
  • 23
  • 165
  • 188
  • I know I can create it by using a loop but this is what I wanted to avoid in the first place. :D – XCS Jun 21 '16 at 16:34