Array.fill(Array) 通过引用而不是值创建副本

IT技术 javascript reference ecmascript-6
2021-01-19 18:59:23

我正在尝试使用创建一个 6 x 12 的矩阵 Array.fill

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

虽然这有效,但问题是内部数组实际上都引用了同一个Array对象。

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

我想(和预期)的值m[1][0]0

如何强制Array.fill填充给定参数的按值复制(例如:Array(12).fill(0)在我的情况下是参数)而不是按引用复制?

3个回答

你可以使用Array.from()代替:

感谢Pranav C Balan在评论中提出关于进一步改进这一点的建议。

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


原始语句(上面优化得更好):

let m = Array.from({length: 6}, e => Array.from({length: 12}, e => 0));
let m = Array.from({length: 6}, e => Array(12).fill(0));
2021-03-11 18:59:23

你不能用.fill(),但你可以用.map()

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

编辑哦等等那行不通;.map()不会遍历未初始化的元素。你可以先填写:

let m = new Array(6).fill(null).map(function() { return new Array(12); });
但是,这将创建一个新数组,而不是原地变异。
2021-03-11 18:59:23
你们这些有新语言功能的孩子需要离开我的草坪
2021-03-15 18:59:23
new Array(6).fill().map(...? 使用箭头函数,它实际上看起来不错。
2021-04-03 18:59:23
@Pointy:我认为Array.from(Array(6)).map(…)无论如何都比那个丑陋的传播运算符更具可读性:-)
2021-04-06 18:59:23
你可以做 [...Array(6)].map(() => Array(12).fill(0))
2021-04-07 18:59:23

你不能用Array#fill方法来做到这一点而是迭代数组并使用 for 循环添加新创建的数组。

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]);

我知道我可以通过使用循环来创建它,但这是我首先想要避免的。:D
2021-04-09 18:59:23