【发布时间】:2018-10-12 18:46:52
【问题描述】:
我正在为我的 JS 课程做一些培训任务,我得到了一个你必须实现一个函数,该函数接受一个正整数 (n) 并返回一个如下所示的矩阵(传递了 5):
[ [ 1, 0, 0, 0, 0 ],
[ 0, 1, 0, 0, 0 ],
[ 0, 0, 1, 0, 0 ],
[ 0, 0, 0, 1, 0 ],
[ 0, 0, 0, 0, 1 ] ]
我能够使用以下代码实现该功能:
function getIdentityMatrix(n) {
const mat = new Array(n).fill([]);
return mat.map((row, index) => {
row = new Array(n).fill(0);
row[index] = 1;
return row;
});
}
但在执行此操作时,我发现了一个我无法解释的奇怪行为......如果我稍微修改一下代码:
function getIdentityMatrix(n) {
const mat = new Array(n).fill(new Array(n).fill(0));
return mat.map((row, index) => {
row[index] = 1;
return row;
});
}
它返回一个像这样的矩阵:
[ [ 1, 1, 1, 1, 1 ],
[ 1, 1, 1, 1, 1 ],
[ 1, 1, 1, 1, 1 ],
[ 1, 1, 1, 1, 1 ],
[ 1, 1, 1, 1, 1 ] ]
为什么会这样?这就像 forEach 函数遍历嵌套在每一行中的所有元素,这是它不应该做的。
感谢您的建议!
【问题讨论】:
-
问题是外部数组中的每个索引都包含对内部数组的相同引用。
-
当你向
.fill()传递一个非基元时,数组的每个索引都将引用同一个对象。您有一个包含 5 个对同一内部数组的引用的数组。 -
由于这不是一个完整的答案,我将其作为评论发布。一个合适的单行替换是
const mat = [...Array(n).keys()].map(() => Array(n).fill(0)) -
@patrick 我更喜欢
Array.from({ length: n }, (_, i1) => Array.from({ length: n }, (_, i2) => +(i1 === i2))); -
@JonasWilms 我认为这比我的更难读,即使它确实替换了整个函数而不仅仅是错误的行。另外我刚刚又做了一个:
[...Array(n).keys()].map(i => Object.assign(Array(n).fill(0), { [i]: 1 }));)
标签: javascript arrays foreach