无法设置矩阵单元格值

时间:2018-10-27 02:17:59

标签: javascript ecmascript-6

为什么要这样做:

let matrix = Array(3).fill(new Array(3).fill(0));
matrix[0][1] = 1

我希望矩阵为:

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

但是,矩阵看起来像这样:

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

因此,它将设置整个列而不是仅设置单元格。我觉得我在这里错过了非常重要的一门语言。

提前谢谢!

3 个答案:

答案 0 :(得分:2)

因为您在内存中为所有索引使用了相同的引用。

想象这是内存,索引指向内存中的相同值,因此,特定索引的每次更改都会修改该值

    new Array(3).fill(0)     Matrix
    +---------+           +-----------+
    | [0,0,0] | <--+------|   Index 0 |
    +---------+    |      +-----------+
          ^        +------|   Index 1 |
          |               +-----------+
          +---------------|   Index 2 |
                          +-----------+

为每个索引创建一个新数组

    {length: 3}, () => Array(3).fill(0)     Matrix
    +---------+                         +-----------+
    | [0,0,0] | <-----------------------|   Index 0 |
    +---------+                         +-----------+
    | [0,0,0] | <-----------------------|   Index 1 |
    +---------+                         +-----------+
    | [0,0,0] | <-----------------------|   Index 2 |
    +---------+                         +-----------+

let matrix = Array.from({length: 3}, () => Array(3).fill(0));
matrix[0][1] = 1;

console.log(matrix);

答案 1 :(得分:1)

当您使用.fill并将其传递给非基元对象(例如对象或数组)时,内存中将只有这些实际对象中的一个。数组将使用对同一对象的三个引用填充,因此,当一个索引发生突变时,它们全部都会被引用。如果要用单独的对象填充数组,则必须在创建新数组的每次迭代中显式创建它们,您可以使用Array.from

const matrix = Array.from(
  { length: 3 },
  () => new Array(3).fill(0)
);
matrix[0][1] = 1;
console.log(matrix);

仅将.fill与基元一起使用,或者当您非常确定时,您希望在一个数组中对同一对象有多个引用。

答案 2 :(得分:1)

由于“外部”数组索引仅引用一个数组,因此您也可以首先fill用零来初始化数组,然后使用map在每个索引处创建新数组:

let matrix = Array(3).fill(0).map(n => new Array(3).fill(0));

matrix[0][1] = 1;
console.log(matrix);