Clonar matrices en JavaScript

C

En uno de mis artículos anteriores, cubrí cómo se pueden copiar objetos en JavaScript. Copiar un objeto es una tarea bastante complicada, dado que también tendría que poder copiar todos los demás tipos de datos que podrían estar en el objeto. Pero, ¿y si solo está copiando una matriz? Al igual que en el último artículo, hay varias formas de realizar esta tarea, algunas de las cuales analizaré en este artículo.

Pero primero, una nota sobre la velocidad. Si bien esto puede no importar para todas las aplicaciones, es algo a considerar si copiar arreglos grandes es una operación común en su código, o si la velocidad realmente importa. Para algunos de los métodos a continuación, noto su velocidad relativa a los otros métodos, que proviene de los resultados de este punto de referencia.

Copia de matrices simples

Para esta primera parte, supongamos que la matriz que desea copiar contiene solo tipos de datos primitivos (e inmutables). Es decir, la matriz solo contiene números, valores booleanos, cadenas, etc. De esta manera podemos centrarnos más en la transferencia de datos de una matriz a otra, en contraposición a cómo manejamos la copia del contenido real de la matriz, lo que haré cubrir en la sección “Copias profundas” a continuación.

Hay una sorprendente cantidad de formas de copiar una matriz, algunas de las cuales incluyen:

  • push
  • Untado
  • slice
  • Array.from
  • _.clone

El operador de propagación y el slice son las formas más rápidas de copiar una matriz superficial, pero tenga en cuenta que esto depende del tiempo de ejecución subyacente, por lo que es posible que no sea universalmente cierto.

empujar

Esta es probablemente la solución más obvia, que recorre la matriz original y usa la nueva matriz push() método para agregar elementos de una matriz a otra:

let oldArr = [3, 1, 5, 2, 9];
let newArr = [];
for (let i=0; i < oldArr.length; i++) {
    newArr.push(oldArr[i]);
}

Simplemente recorremos la matriz que se va a copiar y empujamos cada elemento a la nueva matriz.

Untado

Este método utiliza el operador de propagación, que se definió en ES6 y está disponible en la mayoría de los navegadores actualizados.

Funciona así:

let oldArr = [3, 1, 5, 2, 9];
let newArr = [...oldArr];

Si voy a usar una solución nativa y no una biblioteca de terceros, esta suele ser la solución que prefiero gracias a su sintaxis limpia y simple.

Una nota importante es que esta copia solo funciona en el nivel superior (como muchos de estos métodos), por lo que no debe usarse si necesita copias profundas de algo.

Rebanada

los slice() El método se utiliza normalmente para devolver una parte de una matriz, especificada por el beginning y end parámetros. Sin embargo, si no se pasan parámetros, se devuelve una copia de toda la matriz:

let oldArr = [3, 1, 5, 2, 9];
let newArr = oldArr.slice();

En muchos tiempos de ejecución de JavaScript, esta es la forma más rápida de copiar una matriz.

Matriz. De

los Array.from El método está destinado a crear una copia superficial de cualquier iterable que le pase, y también toma una función de mapeo opcional como segundo parámetro. Por lo tanto, se puede usar para crear una matriz a partir de cadenas, conjuntos, mapas y, por supuesto, otras matrices:

let oldArr = [3, 1, 5, 2, 9];
let newArr = Array.from(oldArr);

Clon de Lodash

Lodash’s clon() y cloneDeep () Los métodos pueden resultarle familiares si lee este artículo sobre cómo copiar objetos. Los métodos hacen exactamente lo que esperarías: cualquier objeto (o matriz, primitivo, etc.) que se le pase se copiará y devolverá.

_.cloneDeep (descrito más adelante) es diferente en el sentido de que no detiene la clonación en el nivel superior, copia recursivamente todos los objetos que encuentra en cualquier nivel.

Dado esto, también podemos usarlo para copiar matrices:

let oldArr = [3, 1, 5, 2, 9];
let newArr = _.clone(oldArr);

_.clone funciona muy bien en comparación con los otros métodos, por lo que si ya está utilizando esta biblioteca en su aplicación, esta es una solución simple.

Copias profundas

Una cosa importante a señalar es que todos los métodos descritos anteriormente solo realizan copias superficiales de sus matrices. Entonces, si tiene una matriz de objetos, por ejemplo, la matriz real se copiará, pero los objetos subyacentes se pasarán por referencia a la nueva matriz.

Para demostrar este problema, veamos un ejemplo:

let oldArr = [{foo: 'bar'}, {baz: 'qux'}];
let newArr = [...oldArr];
console.log(newArr === oldArr);
console.log(newArr[0] === oldArr[0]);
false
true

Aquí puede ver que si bien la matriz real es nueva, los objetos dentro de ella no lo eran. Para algunas aplicaciones, esto puede ser un gran problema. Si esto se aplica a usted, aquí hay algunos otros métodos para probar.

Lodash Clone Deep

Lodash’s _.cloneDeep El método hace exactamente lo mismo que _.clone(), excepto que clona recursivamente todo en la matriz (u objeto) que le pasa. Usando el mismo ejemplo anterior, podemos ver que usando _.cloneDeep() nos proporcionará tanto una nueva matriz como elementos de matriz copiados:

const _ = require('lodash');

let oldArr = [{foo: 'bar'}, {baz: 'qux'}];
let newArr = _.cloneDeep(oldArr);
console.log(newArr === oldArr);
console.log(newArr[0] === oldArr[0]);
false
false

Métodos JSON

JavaScript proporciona algunos métodos JSON útiles que manejan la conversión de la mayoría de los tipos de datos JS en una cadena y luego una cadena JSON válida en un objeto JS. Los métodos respectivos se utilizan de la siguiente manera:

let oldArr = [{foo: 'bar'}, {baz: 'qux'}];
let arrStr = JSON.stringify(oldArr);
console.log(arrStr);

let newArr = JSON.parse(arrStr);
console.log(newArr);

console.log(newArr === oldArr);
console.log(newArr[0] === oldArr[0]);
'[{"foo":"bar"},{"baz":"qux"}]'
[ { foo: 'bar' }, { baz: 'qux' } ]
false
false

Este método funciona muy bien y no requiere bibliotecas de terceros. Sin embargo, hay dos problemas principales:

  • Los datos deben ser serializables y deserializables a través de JSON
  • Usar los métodos JSON de esta manera es mucho más lento que otras soluciones

Por lo tanto, si tiene datos que no se pueden serializar en JSON o si la velocidad es importante para su aplicación, es posible que esta no sea una buena solución para usted.

Conclusión

En este artículo, cubrí una serie de formas en que puede copiar matrices en JavaScript, tanto utilizando código nativo como una útil biblioteca de terceros en Lodash. También analizamos el problema de las matrices de clonación profunda y qué soluciones existen para resolverlo.

¿Existe algún método diferente que funcione mejor para usted? Háganos saber lo que piensa en los comentarios.

 

About the author

Ramiro de la Vega

Bienvenido a Pharos.sh

Soy Ramiro de la Vega, Estadounidense con raíces Españolas. Empecé a programar hace casi 20 años cuando era muy jovencito.

Espero que en mi web encuentres la inspiración y ayuda que necesitas para adentrarte en el fantástico mundo de la programación y conseguir tus objetivos por difíciles que sean.

Add comment

Sobre mi

Últimos Post

Etiquetas

Esta web utiliza cookies propias para su correcto funcionamiento. Al hacer clic en el botón Aceptar, aceptas el uso de estas tecnologías y el procesamiento de tus datos para estos propósitos. Más información
Privacidad