JavaScript tiene muchas formas de hacer cualquier cosa. He escrito sobre 10 formas de escribir tubería / componer en JavaScript, y ahora estamos haciendo arreglos.
1. Operador de propagación (copia superficial)
Desde que cayó ES6, este ha sido el método más popular. Es una sintaxis breve y la encontrará increíblemente útil cuando use bibliotecas como React y Redux.
numbers = [1, 2, 3]; numbersCopy = [...numbers];
Nota: Esto no copia de forma segura matrices multidimensionales. Los valores de matriz / objeto se copian por referencia en lugar de por valor .
Esto esta bien
numbersCopy.push(4); console.log(numbers, numbersCopy); // [1, 2, 3] and [1, 2, 3, 4] // numbers is left alone
Esto no esta 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. Buena antigua para bucle () (copia superficial)
Imagino que este enfoque es el menos popular, dado lo de moda que se ha vuelto la programación funcional en nuestros círculos.
Puro o impuro, declarativo o imperativo, ¡hace el trabajo!
numbers = [1, 2, 3]; numbersCopy = []; for (i = 0; i < numbers.length; i++) { numbersCopy[i] = numbers[i]; }
Nota: Esto no copia de forma segura matrices multidimensionales. Como está utilizando el =
operador, asignará objetos / matrices por referencia en lugar de por valor .
Esto esta bien
numbersCopy.push(4); console.log(numbers, numbersCopy); // [1, 2, 3] and [1, 2, 3, 4] // numbers is left alone
Esto no esta 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. Good Old while () Loop (copia superficial)
Igual que for
—impuro, imperativo, bla, bla, bla ... ¡funciona! ?
numbers = [1, 2, 3]; numbersCopy = []; i = -1; while (++i < numbers.length) { numbersCopy[i] = numbers[i]; }
Nota: Esto también asigna objetos / matrices por referencia en lugar de por valor .
Esto esta bien
numbersCopy.push(4); console.log(numbers, numbersCopy); // [1, 2, 3] and [1, 2, 3, 4] // numbers is left alone
Esto no esta 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 (copia superficial)
De vuelta en territorio moderno, encontraremos la map
función. Enraizado en las matemáticas, map
está el concepto de transformar un conjunto en otro tipo de conjunto, conservando la estructura.
En inglés, eso significa que Array.map
devuelve una matriz de la misma longitud cada vez.
Para duplicar una lista de números, use map
con una double
función.
numbers = [1, 2, 3]; double = (x) => x * 2; numbers.map(double);
¿Qué pasa con la clonación?
Es cierto que este artículo trata sobre la clonación de matrices. Para duplicar una matriz, simplemente devuelva el elemento en su map
llamada.
numbers = [1, 2, 3]; numbersCopy = numbers.map((x) => x);
Si quieres ser un poco más matemático, (x) => x
se llama identidad . Devuelve cualquier parámetro que se le haya dado.
map(identity)
clona una lista.
identity = (x) => x; numbers.map(identity); // [1, 2, 3]
Nota: Esto también asigna objetos / matrices por referencia en lugar de por valor .
5. Array.filter (copia superficial)
Esta función devuelve una matriz, como map
, pero no se garantiza que tenga la misma longitud.
¿Qué pasa si estás filtrando por números pares?
[1, 2, 3].filter((x) => x % 2 === 0); // [2]
La longitud de la matriz de entrada era 3, pero la longitud resultante es 1.
Sin embargo, si su filter
predicado siempre regresa true
, obtendrá un duplicado.
numbers = [1, 2, 3]; numbersCopy = numbers.filter(() => true);
Cada elemento pasa la prueba, por lo que se devuelve.
Nota: Esto también asigna objetos / matrices por referencia en lugar de por valor .
6. Array.reduce (copia superficial)
Casi me siento mal usando reduce
para clonar una matriz, porque es mucho más poderoso que eso. Pero aquí vamos ...
numbers = [1, 2, 3]; numbersCopy = numbers.reduce((newArray, element) => { newArray.push(element); return newArray; }, []);
reduce
transforma un valor inicial mientras recorre una lista.
Aquí el valor inicial es una matriz vacía, y la vamos llenando con cada elemento a medida que avanzamos. Esa matriz debe devolverse de la función que se utilizará en la siguiente iteración.
Nota: Esto también asigna objetos / matrices por referencia en lugar de por valor .
7. Array.slice (copia superficial)
slice
devuelve una copia superficial de una matriz basada en el índice de inicio / finalización proporcionado.
Si queremos los primeros 3 elementos:
[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.