Javascript: wypychanie pustej tablicy 3D
Tworzę pustą tablicę 3D 3x3x1
[
[[],[],[]],
[[],[],[]],
[[],[],[]]
]
Teraz element na pozycji arr[1][1]to [], więc jeśli wykonam arr[1][1].push(1), powinien wstawić 1na pozycjiarr[1][1]
Istnieją 2 metody tworzenia pustej tablicy 3x3x1 w JS, Oto kod,
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)
to znaczy. Poprzez skrót i inny ręcznie, oba arr1i arr2powinny być identyczne, więc powinno być wyjście, ale wynik jest następujący,
[[[], [], []], [[1], [1], [1]], [[], [], []]]
[[[], [], []], [[], [1], []], [[], [], []]]
Dlaczego jest tak, że pierwsza tablica daje takie dane wyjściowe? Czy nie są identyczne?
Chcę, aby dane wyjściowe miały drugą postać. Jeśli jest to niewłaściwy sposób tworzenia pustej tablicy 3x3x1, proszę zasugerować metodę, która daje oczekiwane wyniki.
Odpowiedzi
Użyj jeszcze jednej zagnieżdżonej mapy. Myślę, że to fillwywołanie wypełni pierwszą maptaką samą tablicą w każdym z 2-giego wymiaru zamiast unikalnej, co oznacza, że 2-gi wymiar odnosi się do tej samej tablicy.
Dokumenty z fillnawet zauważają, że valuebędzie dokładnie to samo:
Wartość, którą ma wypełnić tablicę. (Zauważ, że wszystkie elementy w tablicy będą miały dokładnie taką wartość).
Również (tablica jest obiektem):
Jeśli pierwszy parametr jest obiektem, każda szczelina w tablicy będzie się odnosić do tego obiektu.
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],[]],[[],[],[]]]
Innymi słowy:
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]);
Dzieje się tak, ponieważ metoda fill wypełnia „dokładną wartość” we wszystkich trzech.
MDN: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/fill Patrz uwaga w opisie wartości parametru.
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)