Comment cloner un tableau en JavaScript

JavaScript a de nombreuses façons de faire quoi que ce soit. J'ai écrit sur 10 façons d'écrire un tube / composer en JavaScript, et maintenant nous faisons des tableaux.

1. Opérateur de diffusion (copie superficielle)

Depuis la chute d'ES6, c'est la méthode la plus populaire. C'est une syntaxe brève et vous la trouverez incroyablement utile lorsque vous utilisez des bibliothèques comme React et Redux.

numbers = [1, 2, 3]; numbersCopy = [...numbers]; 

Remarque: cela ne copie pas en toute sécurité les tableaux multidimensionnels. Les valeurs de tableau / objet sont copiées par référence plutôt que par valeur .

C'est bon

numbersCopy.push(4); console.log(numbers, numbersCopy); // [1, 2, 3] and [1, 2, 3, 4] // numbers is left alone 

Ce n'est pas bien

nestedNumbers = [[1], [2]]; numbersCopy = [...nestedNumbers]; numbersCopy[0].push(300); console.log(nestedNumbers, numbersCopy); // [[1, 300], [2]] // [[1, 300], [2]] // They've both been changed because they share references 

2. Good Old for () Loop (copie superficielle)

J'imagine que cette approche est la moins populaire, étant donné la façon dont la programmation fonctionnelle à la mode est devenue dans nos cercles.

Pur ou impur, déclaratif ou impératif, il fait le travail!

numbers = [1, 2, 3]; numbersCopy = []; for (i = 0; i < numbers.length; i++) { numbersCopy[i] = numbers[i]; } 

Remarque: cela ne copie pas en toute sécurité les tableaux multidimensionnels. Puisque vous utilisez l' =opérateur, il attribuera des objets / tableaux par référence plutôt que par valeur .

C'est bon

numbersCopy.push(4); console.log(numbers, numbersCopy); // [1, 2, 3] and [1, 2, 3, 4] // numbers is left alone 

Ce n'est pas bien

nestedNumbers = [[1], [2]]; numbersCopy = []; for (i = 0; i < nestedNumbers.length; i++) { numbersCopy[i] = nestedNumbers[i]; } numbersCopy[0].push(300); console.log(nestedNumbers, numbersCopy); // [[1, 300], [2]] // [[1, 300], [2]] // They've both been changed because they share references 

3. Boucle while () Good Old (copie superficielle)

Idem - forimpur, impératif, bla, bla, bla… ça marche! ?

numbers = [1, 2, 3]; numbersCopy = []; i = -1; while (++i < numbers.length) { numbersCopy[i] = numbers[i]; } 

Remarque: Cela affecte également les objets / tableaux par référence plutôt que par valeur .

C'est bon

numbersCopy.push(4); console.log(numbers, numbersCopy); // [1, 2, 3] and [1, 2, 3, 4] // numbers is left alone 

Ce n'est pas bien

nestedNumbers = [[1], [2]]; numbersCopy = []; i = -1; while (++i < nestedNumbers.length) { numbersCopy[i] = nestedNumbers[i]; } numbersCopy[0].push(300); console.log(nestedNumbers, numbersCopy); // [[1, 300], [2]] // [[1, 300], [2]] // They've both been changed because they share references 

4. Array.map (copie superficielle)

De retour en territoire moderne, nous trouverons la mapfonction. Enraciné dans les mathématiques, mapest le concept de transformation d'un ensemble en un autre type d'ensemble, tout en préservant la structure.

En anglais, cela signifie Array.maprenvoie un tableau de même longueur à chaque fois.

Pour doubler une liste de nombres, utilisez mapavec une doublefonction.

numbers = [1, 2, 3]; double = (x) => x * 2; numbers.map(double); 

Et le clonage?

Certes, cet article concerne le clonage de tableaux. Pour dupliquer un tableau, renvoyez simplement l'élément dans votre mapappel.

numbers = [1, 2, 3]; numbersCopy = numbers.map((x) => x); 

Si vous souhaitez être un peu plus mathématique, cela (x) => xs'appelle l' identité . Il renvoie le paramètre qui lui a été donné.

map(identity) clone une liste.

identity = (x) => x; numbers.map(identity); // [1, 2, 3] 

Remarque: Cela affecte également les objets / tableaux par référence plutôt que par valeur .

5. Array.filter (copie superficielle)

Cette fonction renvoie un tableau, tout comme map, mais il n'est pas garanti qu'il ait la même longueur.

Et si vous filtrez pour des nombres pairs?

[1, 2, 3].filter((x) => x % 2 === 0); // [2] 

La longueur du tableau d'entrée était de 3, mais la longueur résultante est de 1.

Si votre filterprédicat revient toujours true, cependant, vous obtenez un double!

numbers = [1, 2, 3]; numbersCopy = numbers.filter(() => true); 

Chaque élément passe le test, il est donc renvoyé.

Remarque: Cela affecte également les objets / tableaux par référence plutôt que par valeur .

6. Array.reduce (copie superficielle)

Je me sens presque mal d'utiliser reducepour cloner un tableau, car c'est tellement plus puissant que ça. Mais on y va…

numbers = [1, 2, 3]; numbersCopy = numbers.reduce((newArray, element) => { newArray.push(element); return newArray; }, []); 

reduce transforme une valeur initiale lorsqu'elle parcourt une liste.

Ici, la valeur initiale est un tableau vide, et nous le remplissons avec chaque élément au fur et à mesure. Ce tableau doit être renvoyé par la fonction à utiliser dans l'itération suivante.

Remarque: Cela affecte également les objets / tableaux par référence plutôt que par valeur .

7. Array.slice (copie superficielle)

slicerenvoie une copie superficielle d'un tableau basé sur l'index de début / fin fourni que vous fournissez.

Si nous voulons les 3 premiers éléments:

[1, 2, 3, 4, 5].slice(0, 3); // [1, 2, 3] // Starts at index 0, stops at index 3 

If we want all the elements, don’t give any parameters

numbers = [1, 2, 3, 4, 5]; numbersCopy = numbers.slice(); // [1, 2, 3, 4, 5] 

Note: This is a shallow copy, so it also assigns objects/arrays by reference instead of by value.

8. JSON.parse and JSON.stringify (Deep copy)

JSON.stringify turns an object into a string.

JSON.parse turns a string into an object.

Combining them can turn an object into a string, and then reverse the process to create a brand new data structure.

Note: This onesafely copies deeply nested objects/arrays!

nestedNumbers = [[1], [2]]; numbersCopy = JSON.parse(JSON.stringify(nestedNumbers)); numbersCopy[0].push(300); console.log(nestedNumbers, numbersCopy); // [[1], [2]] // [[1, 300], [2]] // These two arrays are completely separate! 

9. Array.concat (Shallow copy)

concat combines arrays with values or other arrays.

[1, 2, 3].concat(4); // [1, 2, 3, 4] [1, 2, 3].concat([4, 5]); // [1, 2, 3, 4, 5] 

If you give nothing or an empty array, a shallow copy’s returned.

[1, 2, 3].concat(); // [1, 2, 3] [1, 2, 3].concat([]); // [1, 2, 3] 

Note: This also assigns objects/arrays by reference instead of by value.

10. Array.from (Shallow copy)

This can turn any iterable object into an array. Giving an array returns a shallow copy.

numbers = [1, 2, 3]; numbersCopy = Array.from(numbers); // [1, 2, 3] 

Note: This also assigns objects/arrays by reference instead of by value.

Conclusion

Well, this was fun ?

I tried to clone using just 1 step. You’ll find many more ways if you employ multiple methods and techniques.