Javascript 数组矩阵和forEach行为的差异
我在为我的JS课程做一些培训任务,我得到了一个必须实现一个函数的任务,该函数接受一个正整数(n)并返回一个如下矩阵(传递了5个): 我能够使用以下代码实现该功能:Javascript 数组矩阵和forEach行为的差异,javascript,arrays,foreach,Javascript,Arrays,Foreach,我在为我的JS课程做一些培训任务,我得到了一个必须实现一个函数的任务,该函数接受一个正整数(n)并返回一个如下矩阵(传递了5个): 我能够使用以下代码实现该功能: function getIdentityMatrix(n) { const mat = new Array(n).fill([]); return mat.map((row, index) => { row = new Array(n).fill(0); row[index] = 1; retur
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函数迭代嵌套在每行中的所有元素一样,它不应该这样做
谢谢你的建议 这是因为数组是引用类型。当你这样做的时候
新数组(n).fill(新数组(n).fill(0))
首先,内部的新数组(n).fill(0)
使数组大小n填充0
;接下来,外部数组(n).fill创建一个数组,该数组中填充了对该内部数组的n个引用
它不创建n个内部数组,只创建n个对同一数组的引用。因此,当您更改该内部数组的元素时,外部数组中的所有引用都将反映更改,因为它们都指向同一对象
// 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;
只有1个嵌套数组,而不是n次数组。所讨论的代码与此等效:
设n=5
让innerArr=新数组(n).填充(0)
函数getIdentityMatrix(n){
const mat=新数组(n).fill(innerArr);
返回mat.map((行,索引)=>{
行[索引]=1;
返回行;
});
}
console.log(getIdentityMatrix(n))
问题是外部数组中的每个索引都包含对内部数组的相同引用。当您将非原语传递给.fill()
时,数组的每个索引都将引用相同的对象。你有一个5个对同一个内部数组的引用的数组。因为这不是一个完整的答案,所以我将此作为一个注释发布。一个合适的单行替换将是const mat=[…Array(n).keys()].map(()=>Array(n).fill(0))
@patrick我更喜欢Array.from({length:n},(1)=>Array.from({length:n},(2)=>+(i1==i2))代码>@jonaswillms我认为这比我的更难理解,尽管它确实取代了整个函数,而不仅仅是错误的行。我还做了另一个:[…数组(n).keys()].map(I=>Object.assign(数组(n).fill(0),{[I]:1}))
;)
// 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;