Javascript splice and push in for循环多次添加项

Javascript splice and push in for loop adds items multiple times

我正尝试通过实施 Conway 的生命游戏来学习 Javascript,但不幸的是,我一开始就卡住了。

我有一个矩阵:

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

并想模拟围绕矩阵的“1”边框。 我的最终矩阵应该是:

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

到目前为止,我已经编写了以下代码:

var matrix = [[0,0,0,0], [0,0,0,0], [0,0,0,0], [0,0,0,0]];

function addBorder(m) {

  var row = []
  for (var i=0; i<m[0].length; i++) {
    row.push(0);
  }

  m.splice(0, 0, row);
  m.push(row);

  for (var i=0; i<m.length; i++) {
    m[i].splice(0,0,1);
    m[i].push(1);
  }

  return m;
}

addBorder(matrix).forEach(i => console.log(i.join(',')))

输出矩阵几乎是我想要的,但不完全是。但是,如果我将第二个 for 循环更改为 (var i=0; i<m.length; i++),代码将生成正确的矩阵。不幸的是,我不知道为什么它最初不起作用,但使用这个改变的代码行。为什么它在第一个和最后一个循环中添加两个项目?我很感激任何提示!

第一行和最后一行多出1的原因是相同row-object。您应该避免在矩阵中放置两次相同的行对象。

所以改变:

m.splice(0, 0, row);
m.push(row);

至:

m.splice(0, 0, row);
m.push([...row]); // create a copy of row, and push that.

现在,当您执行循环以前缀和后缀 1 时,您将确保每次都针对不同的行对象。

不相关,但 m.unshift(row)m.splice(0, 0, row) 相同。

以更实用的方式,在不改变原始数组的情况下,您可以这样编写函数:

function addBorder(m) {
     return [
         Array(m.length+2).fill(1),
         ...m.map(row => [1, ...row, 1]),
         Array(m.length+2).fill(1)
     ];
}

var matrix = [[0,0,0,0], [0,0,0,0], [0,0,0,0], [0,0,0,0]];

console.log(addBorder(matrix));

当然,你仍然可以决定将结果赋值给原始矩阵变量:

matrix = addBorder(matrix)