如何正确编辑预填充(fixed)二维数组的元素?
问题:二维数组批量修改异常原因与解决方法
为优化性能,尝试声明一个n*n的预填充二维数组,代码如下:
let n=5; let cellTemplate="abc"; let array=new Array(n).fill(new Array(n).fill(cellTemplate));
预期初始数组结构为:
[ ["abc","abc","abc","abc","abc"], ["abc","abc","abc","abc","abc"], ["abc","abc","abc","abc","abc"], ["abc","abc","abc","abc","abc"], ["abc","abc","abc","abc","abc"] ]
但执行array[0][1]="xxx"修改元素时,所有行的对应位置都变为"xxx",结果如下:
[ ["abc","xxx","abc","abc","abc"], ["abc","xxx","abc","abc","abc"], ["abc","xxx","abc","abc","abc"], ["abc","xxx","abc","abc","abc"], ["abc","xxx","abc","abc","abc"] ]
执行array[0].push("xxx")也会出现所有行同步新增元素的问题,而用let array=[]声明的普通数组无此异常。
原因分析
Array.prototype.fill()方法传入对象(包括数组)时,传递的是引用而非副本。外层数组的fill方法会将同一个内层数组的引用填充到每一个位置,所以所有行实际上指向的是同一个数组实例。修改其中任意一行的元素,都会同步反映到所有行上。
解决方法
方法1:使用
Array.from()创建独立内层数组
通过Array.from()的映射函数,为外层数组每个位置生成新的内层数组,确保每行都是独立实例:let n=5; let cellTemplate="abc"; let array=Array.from({length:n}, ()=>new Array(n).fill(cellTemplate));方法2:利用
map()生成独立行
先初始化外层数组,再通过map遍历每个位置,创建新的内层数组:let n=5; let cellTemplate="abc"; let array=new Array(n).fill().map(()=>new Array(n).fill(cellTemplate));注:
new Array(n).fill()用于填充外层数组为可遍历的undefined元素,保证map能遍历所有位置。方法3:嵌套循环手动构建
逻辑直观的传统写法,逐行逐元素创建,完全避免引用共享问题:let n=5; let cellTemplate="abc"; let array=[]; for(let i=0;i<n;i++){ let row=[]; for(let j=0;j<n;j++){ row.push(cellTemplate); } array.push(row); }
内容的提问来源于stack exchange,提问作者Silver
相关产品推荐
相关产品推荐

