我正在为我的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函数对嵌套在每一行中的所有元素进行迭代一样,它不应该这样做。
谢谢你的建议!
发布于 2018-10-12 10:56:13
这是因为Array是一个引用类型。当你做的时候
new Array(n).fill(new Array(n).fill(0))
首先,内部new Array(n).fill(0)
使数组大小n填充0
;接下来,外部Array(n).fill
创建一个由对该内部数组的n个引用填充的数组。
它不创建n个内部数组,只创建对同一个数组的n个引用。因此,当您更改该内部数组的一个元素时,外部数组中的所有引用都将反映更改,因为它们都指向同一个对象。
发布于 2018-10-12 17:02:01
所涉守则相当于:
let n = 5
let innerArr = new Array(n).fill(0)
function getIdentityMatrix(n) {
const mat = new Array(n).fill(innerArr);
return mat.map((row, index) => {
row[index] = 1;
return row;
});
}
console.log(getIdentityMatrix(n))
因为您使用的是fill
,所以基本上是用对innerArr
(which you can see clearly from the above console output)
的引用填充这个mat
数组。
然后对每个i row[index] = 1
进行,它将更改相同数组的相同值(在I索引处)。
现在你的例子..。可以用较短的形式写成:
const getIdentityMatrix = (n) =>
[...Array(n)].map((row, index) => {
row = Array(n).fill(0)
row[index] = 1
return row
})
console.log(getIdentityMatrix(3))
显然,maps
在新创建的n
数组上,然后是spreaded
数组上,但是随后用一个全新的数组引用覆盖了每个元素。
由于该引用是全新的,所以使用row[index] = 1
修改它会在我们从地图上进行return the x
时产生预期的行为。
另一种在一行中实现这一目标的方法是通过map
、Object.assign和Object.values实现如下:
const gm = (n) => [...Array(n)].map((x,i) =>
Object.values(Object.assign(Object.assign({}, Array(n).fill(0)), {[i]:1})))
console.log(gm(3))
发布于 2018-10-12 11:03:27
// your example is roughly equivalent to this.
const innerArray = new Array(n).fill(0);
const mat = new Array(n).fill(innerArray);
(mat[0] === mat[1] === innerArray) === true;
只有一个嵌套数组,而不是n次数组。
https://stackoverflow.com/questions/52785440
复制相似问题