[英]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 []; } );
正如您可以注意到使用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.