Javascript: การพุชในอาร์เรย์ 3 มิติที่ว่างเปล่า

Oct 06 2020

ฉันสร้างอาร์เรย์ 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 ว่างโปรดแนะนำวิธีการที่จะให้ผลลัพธ์ที่คาดหวัง

คำตอบ

3 zero298 Oct 06 2020 at 16:53

ใช้อีกหนึ่งแผนที่ซ้อนกัน ฉันคิดว่าการ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]);

2 SachinNayak Oct 06 2020 at 16:57

สาเหตุที่เกิดขึ้นเป็นเพราะวิธีการเติมเติม "ค่าที่แน่นอน" ในทั้งสาม

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)