想實(shí)現(xiàn)的目標(biāo)
在js/ts(typescript)項(xiàng)目,經(jīng)常會(huì)遇到使用二維數(shù)組的場(chǎng)景潘明,但js/ts中沒有直接的二維數(shù)組可以使用蛋欣,間接實(shí)現(xiàn)方法是嵌套一維數(shù)組寡夹。
現(xiàn)在項(xiàng)目需初始化NxN的二維數(shù)組处面,且每個(gè)元素為0,然后程序會(huì)根據(jù)邏輯要求菩掏,更新其中的某個(gè)元素值魂角。這有點(diǎn)像是NxN的稀疏矩陣。
初版實(shí)現(xiàn)
有了上述需求智绸,很容易寫出初始化的語句:
let N = 3;
let arr1 = new Array(N).fill(new Array(N).fill(0));
...
arr1[1][2] = 1;
...
代碼很簡(jiǎn)潔野揪,先new Array(N)出N行,再在N行中填充N列瞧栗,N列同樣使用new Array方式進(jìn)行創(chuàng)建并初始化為0斯稳,在創(chuàng)建完后通過輸出arr1值,可以看出迹恐,確實(shí)是生成NxN的0矩陣:原因
經(jīng)過再次仔細(xì)上述簡(jiǎn)短的代碼,左看右看還是沒有想到原因在哪里廊酣,最后通過瀏覽器的F12工具驗(yàn)證:把問題范圍縮小到
new Array(N).fill(new Array(N).fill(0));
這條語句上:原來是JS引用導(dǎo)致的問題D艹堋!亡驰!
這條語句晓猛,應(yīng)該先是創(chuàng)建了N行數(shù)組,接著調(diào)用fill函數(shù)時(shí)凡辱,先計(jì)算N列的創(chuàng)建并初始化為N列全0數(shù)組戒职,然后再把N列數(shù)組傳入到原fill函數(shù)中,此時(shí)傳入的N列是同一個(gè)對(duì)象透乾,因此N行數(shù)組的每一行的子數(shù)組都指向了同一個(gè)N列洪燥,也就當(dāng)更新某一個(gè)元素時(shí)磕秤,所有列都變化了,因?yàn)檎麄€(gè)數(shù)組實(shí)際就1行N列捧韵。此語句應(yīng)等效于(僅為推測(cè)市咆,未查看底層js實(shí)際執(zhí)行過程哈):
let n_cols = new Array(N).fill(0);
let arr1 = new Array(N).fill(n_cols);
整改
let N = 3;
let arr1 = new Array(N).fill(0).map((val) => new Array(N).fill(0));
...
arr1[1][2] = 1;
...
這次就成功啦:注意:
需先對(duì)N行使用fill(0)填充后,map才有效果哦!!!