簡體   English   中英

由Array.prototype.fill()填充的數組的奇怪行為

[英]Strange behavior of an array filled by Array.prototype.fill()

我面對一些我不理解的陣列。 實際上,我創建了一個我用空子數組填充的數組來獲得2D矩陣。 但是當我操縱數組時,它的行為並不像我預期的那樣。

var arr = new Array(5);
arr.fill([]);
arr[2].push("third rank item");
console.log(arr);

//[ [ 'third rank item' ],
//  [ 'third rank item' ],
//  [ 'third rank item' ],
//  [ 'third rank item' ],
//  [ 'third rank item' ] ]

關於此事的每一個亮點都會受到歡迎

這與數組(以及通常的對象)是引用而不是值是同樣的老問題。

具體來說,當您執行arr.fill([]) ,您將獲取一個單個空數組並使用它來填充父數組。

這就像說:

var arr = new Array(5);
arr[0] = arr[1] = arr[2] = arr[3] = arr[4] = [];

它們都引用相同的數組! 所以當你繼續修改其中一個時,看起來它們都被修改了(但實際上它仍然是相同的)

不幸的是,沒有簡單的方法為每個人分配一個空數組。 你可以這樣做:

Array.apply(null, Array(5)).map(function() {return [];});

實質上,創建一個長度為5的(初始化的)空數組,並將每個(空)值映射到新的[]

編輯:好像我以前被困住了。 根據@ torazaburo的評論,您可以使用Array.from而不是Array.apply(null, Array(5)).map ,如下所示:

Array.from( new Array(5), function() { return []; } );

ECMA的Array.prototype.fill 文檔的第11行顯然給出了神秘的原因。

重復,而k <最終

設Pk為ToString(k)。

設setStatus為Set(O,Pk,value,true)。

ReturnIfAbrupt(setStatus)。

將k增加1。

這里的“價值”只是收到的參考。 他們將它設置為直接排列的屬性。 這意味着所有填充的數組只是對單個數組對象的引用。

正如您可以注意到使用array.fill,您將使用對同一數組的引用填充數組,

如果要將每個數組索引實例化為空數組,則正常的while循環將執行:

 var arr = []; var n = 5 while(n--) arr[n] = [] arr[2].push("third rank item"); console.log(arr); 

選項2:
如果你有lodash包可用,你也可以使用_.map,因為這是專門設計來循環稀疏數組(本機映射將跳過非init值)

 var arr =_.map(new Array(5), (x => [])) arr[2].push("third rank item"); console.log(arr) 
 <script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.2/lodash.min.js"></script> 

這是引用的原因。 數組是一種對象,當你用[] or new Array()填充你的數組時,對象就會對它們的引用起作用,並且在所有索引中放入相同的數組,這就是更新子數組時更新所有索引的原因。

解:

let arr = new Array(5).fill(0).map(ele => ele = []); arr[2].push("something");

要么

let arr = Array.of([], [], [], []); arr[2].push("something");

結果:正如預期的那樣,只更新了2個arr索引。

你可以試試這個,

 var arr = new Array(5); var i = 0; while (i < arr.length) arr.fill([], i++); arr[2].push("third rank item"); console.log(arr); 

試試這個,這是一個快速的解決方案。

 var arr = new Array(5); arr = Array.from(arr, x => []); arr[2].push("third rank item"); console.log(arr); 

使用ES6,我建議使用此方法創建2個或多維數組:

// create an M x N dimension grid and fill it with 0's
const myArray = [...Array(M)].map(r => [...Array(N)].map(r => 0));

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM