Javascript: pousser dans un tableau 3d vide

Oct 06 2020

Je crée un tableau 3D vide 3x3x1

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

Maintenant, l'élément à la position arr[1][1]est [], donc, si je l'exécute, arr[1][1].push(1)il doit s'insérer 1en positionarr[1][1]

Il existe 2 méthodes pour créer un tableau 3x3x1 vide dans JS, voici le code,

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)

c'est à dire. Grâce à un raccourci et un autre manuellement, les deux arr1et arr2devraient être identiques, ainsi devrait être la sortie, mais la sortie est la suivante,

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

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

Pourquoi ce premier tableau donne-t-il une telle sortie? Les deux ne sont-ils pas identiques?

Je veux que la sortie soit de la 2ème forme, si c'est une mauvaise façon de créer un tableau 3x3x1 vide, veuillez suggérer une méthode telle qu'elle donne la sortie attendue.

Réponses

3 zero298 Oct 06 2020 at 16:53

Utilisez une autre carte imbriquée. Je pense que cet fillappel remplira le premier mapavec le même tableau dans chacune de la 2ème dimension au lieu d'un unique, ce qui signifie que la 2ème dimension fait toutes référence au même tableau.

Les documents de fillmême notent que le valuesera exactement le même:

Valeur avec laquelle remplir le tableau. (Notez que tous les éléments du tableau auront cette valeur exacte.)

Aussi (le tableau est un objet):

Si le premier paramètre est un objet, chaque emplacement du tableau référencera cet objet.

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

En d'autres termes:

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

La raison pour laquelle cela se produit est que la méthode de remplissage remplit la «valeur exacte» dans les trois.

MDN: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/fill Voir la remarque dans la description de la valeur du paramètre.

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)