Clonar matrices en JavaScript

    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.

     

    Etiquetas:

    Deja una respuesta

    Tu direcci贸n de correo electr贸nico no ser谩 publicada. Los campos obligatorios est谩n marcados con *