Javascript: Mendorong dalam Larik 3d Kosong

Oct 06 2020

Saya membuat array 3D 3x3x1 kosong

[
  [[],[],[]],
  [[],[],[]],
  [[],[],[]]
]

Sekarang, Elemen pada posisi arr[1][1]adalah [], Jadi, Jika saya mengeksekusinya arr[1][1].push(1)harus dimasukkan 1pada posisiarr[1][1]

Ada 2 metode untuk membuat array 3x3x1 kosong di JS, Ini kodenya,

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)

yaitu. Melalui jalan pintas dan lainnya secara manual, keduanya arr1dan arr2harus identik, jadi harus menjadi keluaran, Tetapi keluarannya adalah sebagai berikut,

[[[], [], []], [[1], [1], [1]], [[], [], []]]

[[[], [], []], [[], [1], []], [[], [], []]]

Mengapa larik pertama memberikan keluaran seperti itu? Bukankah keduanya identik?

Saya ingin hasilnya berupa bentuk ke-2, Jika ini adalah cara yang salah untuk membuat larik 3x3x1 kosong, harap sarankan metode sedemikian rupa sehingga memberikan keluaran yang diharapkan.

Jawaban

3 zero298 Oct 06 2020 at 16:53

Gunakan satu peta bersarang lagi. Saya pikir fillpanggilan itu akan mengisi yang pertama mapdengan array yang sama di masing-masing dimensi ke-2, bukan yang unik yang berarti semua dimensi ke-2 mengacu pada array yang sama.

Dokumen dari fillcatatan genap bahwa valueakan sama persis:

Nilai untuk mengisi larik. (Perhatikan bahwa semua elemen dalam larik akan menjadi nilai persis seperti ini.)

Juga (array adalah objek):

Jika parameter pertama adalah sebuah objek, setiap slot dalam array akan mereferensikan objek tersebut.

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],[]],[[],[],[]]]

Dengan kata lain:

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

Alasan ini terjadi karena metode pengisian mengisi "nilai yang tepat" di ketiganya.

MDN: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/fill Lihat Catatan di Deskripsi nilai parameter.

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)