Javascript: Empurrando uma matriz 3d vazia

Oct 06 2020

Eu crio uma matriz 3D 3x3x1 vazia

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

Agora, o elemento na posição arr[1][1]é [], então, se eu executar, arr[1][1].push(1)ele deve inserir 1na posiçãoarr[1][1]

Existem 2 métodos para criar uma matriz 3x3x1 vazia em JS. Aqui está o código,

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)

ou seja, Através de atalho e outro manualmente, ambos arr1e arr2devem ser idênticos, então deve ser a saída, mas a saída é a seguinte,

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

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

Por que o primeiro array fornece tal saída? Ambos não são idênticos?

Quero que a saída seja da 2ª forma. Se essa for uma maneira errada de criar uma matriz 3x3x1 vazia, sugira um método que forneça a saída esperada.

Respostas

3 zero298 Oct 06 2020 at 16:53

Use mais um mapa aninhado. Acho que essa fillchamada preencherá o primeiro mapcom o mesmo array em cada uma das 2ª dimensão em vez de um único, o que significa que a 2ª dimensão faz referência ao mesmo array.

Os documentos do fillmesmo observam que valueserá exatamente o mesmo:

Valor com o qual preencher a matriz. (Observe que todos os elementos da matriz terão este valor exato.)

Além disso (array é um objeto):

Se o primeiro parâmetro for um objeto, cada slot na matriz fará referência a esse objeto.

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

Em outras palavras:

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

A razão disso acontecer é porque o método de preenchimento preenche o "valor exato" em todos os três.

MDN: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/fill Consulte a nota na descrição do valor do parâmetro.

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)