Come clonare un array in JavaScript

JavaScript ha molti modi per fare qualsiasi cosa. Ho scritto su 10 modi per scrivere pipe / comporre in JavaScript e ora stiamo creando array.

1. Operatore di diffusione (copia superficiale)

Da quando è uscito ES6, questo è stato il metodo più popolare. È una sintassi breve e la troverai incredibilmente utile quando usi librerie come React e Redux.

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

Nota: questo non copia in modo sicuro gli array multidimensionali. I valori di matrice / oggetto vengono copiati per riferimento anziché per valore .

Questo va bene

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

Questo non va bene

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 (Shallow copy)

Immagino che questo approccio sia il meno popolare, visto come la programmazione funzionale alla moda è diventata nei nostri circoli.

Puro o impuro, dichiarativo o imperativo, fa il suo lavoro!

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

Nota: questo non copia in modo sicuro gli array multidimensionali. Dato che stai usando l' =operatore, assegnerà oggetti / array per riferimento invece che per valore .

Questo va bene

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

Questo non va bene

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. Good Old while () Loop (copia superficiale)

Uguale a for—impure, imperative, blah, blah, blah… funziona! ?

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

Nota: questo assegna anche oggetti / array per riferimento invece che per valore .

Questo va bene

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

Questo non va bene

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 (copia superficiale)

Tornando al territorio moderno, troveremo la mapfunzione. Radicato nella matematica, mapè il concetto di trasformare un insieme in un altro tipo di insieme, preservando la struttura.

In inglese, ciò significa che Array.maprestituisce ogni volta un array della stessa lunghezza.

Per raddoppiare un elenco di numeri, utilizzare mapcon una doublefunzione.

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

E la clonazione ??

È vero, questo articolo riguarda la clonazione di array. Per duplicare un array, restituisci semplicemente l'elemento nella tua mapchiamata.

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

Se vuoi essere un po 'più matematico, (x) => xsi chiama identità . Restituisce qualunque parametro sia stato fornito.

map(identity) clona un elenco.

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

Nota: questo assegna anche oggetti / array per riferimento invece che per valore .

5. Array.filter (copia superficiale)

Questa funzione restituisce un array, proprio come map, ma non è garantito che abbia la stessa lunghezza.

E se filtrassi i numeri pari?

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

La lunghezza dell'array di input era 3, ma la lunghezza risultante è 1.

Se il tuo filterpredicato ritorna sempre true, tuttavia, ottieni un duplicato!

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

Ogni elemento supera il test, quindi viene restituito.

Nota: questo assegna anche oggetti / array per riferimento invece che per valore .

6. Array.reduce (copia superficiale)

Quasi mi dispiace usare reduceper clonare un array, perché è molto più potente di così. Ma eccoci qui ...

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

reduce trasforma un valore iniziale mentre scorre un elenco.

Qui il valore iniziale è un array vuoto e lo riempiamo con ogni elemento mentre procediamo. Quell'array deve essere restituito dalla funzione per essere utilizzato nell'iterazione successiva.

Nota: questo assegna anche oggetti / array per riferimento invece che per valore .

7. Array.slice (copia superficiale)

slicerestituisce una copia superficiale di un array in base all'indice iniziale / finale fornito.

Se vogliamo i primi 3 elementi:

[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.