Javascript: การพุชในอาร์เรย์ 3 มิติที่ว่างเปล่า
ฉันสร้างอาร์เรย์ 3 มิติ 3x3x1 ว่างเปล่า
[
[[],[],[]],
[[],[],[]],
[[],[],[]]
]
ตอนนี้องค์ประกอบที่ตำแหน่งarr[1][1]คือ[]ดังนั้นถ้าฉันดำเนินการarr[1][1].push(1)ควรแทรก1ในตำแหน่งarr[1][1]
มี 2 วิธีในการสร้างอาร์เรย์ 3x3x1 ว่างใน JS นี่คือรหัส
var arr1 = [...new Array(3)].map(e => [...new Array(3)].fill([]));
var arr2 = [[[],[],[]],[[],[],[]],[[],[],[]]];
arr1[1][1].push(1);
arr2[1][1].push(1);
console.log(arr1)
console.log(arr2)
กล่าวคือ. ผ่านทางลัดและอื่นด้วยตนเองทั้งสองอย่างarr1และarr2ควรเหมือนกันดังนั้นควรเป็นผลลัพธ์ แต่ผลลัพธ์จะเป็นดังนี้
[[[], [], []], [[1], [1], [1]], [[], [], []]]
[[[], [], []], [[], [1], []], [[], [], []]]
เหตุใดอาร์เรย์แรกจึงให้เอาต์พุตดังกล่าว ทั้งสองไม่เหมือนกัน?
ฉันต้องการให้ผลลัพธ์เป็นรูปแบบที่ 2 หากนี่เป็นวิธีที่ไม่ถูกต้องในการสร้างอาร์เรย์ 3x3x1 ว่างโปรดแนะนำวิธีการที่จะให้ผลลัพธ์ที่คาดหวัง
คำตอบ
ใช้อีกหนึ่งแผนที่ซ้อนกัน ฉันคิดว่าการfillเรียกนั้นจะเติมอาร์เรย์แรกmapด้วยอาร์เรย์เดียวกันในแต่ละมิติที่ 2 แทนที่จะเป็นแบบที่ไม่ซ้ำกันซึ่งหมายความว่ามิติที่ 2 ทั้งหมดอ้างอิงอาร์เรย์เดียวกัน
เอกสารจากfillแม้จะทราบว่าvalueจะเหมือนกันทุกประการ:
ค่าที่จะเติมอาร์เรย์ด้วย (โปรดทราบว่าองค์ประกอบทั้งหมดในอาร์เรย์จะเป็นค่าที่แน่นอนนี้)
นอกจากนี้ (อาร์เรย์เป็นวัตถุ):
หากพารามิเตอร์แรกเป็นวัตถุแต่ละสล็อตในอาร์เรย์จะอ้างอิงออบเจ็กต์นั้น
const arr1 = [...new Array(3)].map(e => [...new Array(3)].fill([]));
const arr2 = [[[],[],[]],[[],[],[]],[[],[],[]]];
const arr3 = [...new Array(3)].map(() => [...new Array(3)].map(() => []));
arr1[1][1].push(1);
arr2[1][1].push(1);
arr3[1][1].push(1);
console.log(JSON.stringify(arr1)); // [[[],[],[]],[[1],[1],[1]],[[],[],[]]]
console.log(JSON.stringify(arr2)); // [[[],[],[]],[[],[1],[]],[[],[],[]]]
console.log(JSON.stringify(arr3)); // [[[],[],[]],[[],[1],[]],[[],[],[]]]
กล่าวอีกนัยหนึ่ง:
const expandedArr1 = [...new Array(3)].map(() => {
/*
* From MDN fill documentation:
* Value to fill the array with. (Note all elements in the array will be this exact value.)
*/
return [...new Array(3)].fill([]); // Every element will get this exact value (reference)
});
// They are the same reference:
console.log(expandedArr1[1][1] === expandedArr1[1][2]);
สาเหตุที่เกิดขึ้นเป็นเพราะวิธีการเติมเติม "ค่าที่แน่นอน" ในทั้งสาม
MDN: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/fill ดูหมายเหตุในคำอธิบายค่าพารามิเตอร์
var arr1 = [...new Array(3)].map(e => [...new Array(3)].map(e=>[])); // Note that i have used a map with a function returning an array([]) instead of your fill method
var arr2 = [[[],[],[]],[[],[],[]],[[],[],[]]];
arr1[1][1].push(1);
arr2[1][1].push(1);
console.log(arr1)
console.log(arr2)