La copia de un array de objetos en otro array en javascript utilizando rebanada(0) y concat() no funciona.

He intentado lo siguiente para probar si puedo obtener el comportamiento esperado de copia en profundidad el uso de este. Pero la matriz original es también modificado después de hacer cambios en la copia de la matriz.

var tags = [];
for(var i=0; i<3; i++) {
    tags.push({
        sortOrder: i,
        type: 'miss'
    })
}
for(var tag in tags) { 
    if(tags[tag].sortOrder == 1) {
        tags[tag].type = 'done'
    }
}
console.dir(tags)

var copy = tags.slice(0)
console.dir(copy)

copy[0].type = 'test'
console.dir(tags)

var another = tags.concat()
another[0].type = 'miss'
console.dir(tags)

¿Cómo puedo hacer una copia en profundidad de una matriz a otra, de modo que la matriz original no se modifica si puedo hacer un cambio en la copia de la matriz.

  • No estoy seguro de lo que estás tratando de hacer, pero. Sugiero cambiar su segundo bucle for para un for of bucle for of(var tag of tags) { if(tag.sortOrder == 1) { tag.type == 'done' }}
  • Dependiendo de su entorno, puede probar con el Objeto.crear?
  • puede dar un ejemplo de la misma
  • Oh, var newObject = Objeto.crear(oldObject) debe darle un proto en base y sin referencia clon de la antigua objeto. No estoy seguro acerca de las matrices, comprar usted puede intentar. El entorno de parte del comentario es que no sé si estás en V8 o tal vez otro JS motores, creo que no es apoyada por todas partes (pero hay polyfils).
  • En realidad parece ser que es: kangax.github.io/compat-tabla/es5/#Objeto.crear
InformationsquelleAutor jsbisht | 2015-02-12

9 Comentarios

  1. 67

    Intentar

    var copy = JSON.parse(JSON.stringify(tags));
    • Estoy utilizando el mismo ahora. Este funciona a la perfección.
    • Más de una sí y una media de edad, y todavía útil !
    • No tengo idea de por qué esto funciona
    • Esto es INCREÍBLE, ya que ayuda a copiar objetos anidados… un millón de Gracias por compartir!!!
    • Bien, esto funciona porque estás serializar la matriz/objeto en una cadena. Al analizar esa cadena, totalmente nueva, los objetos se crean instancias, como si recibió una carga útil de algunos de api. Las referencias no se conservan, aunque, así que si usted tiene los elementos de la matriz que señalan a otros elementos, este va a ser peligroso.
    • De acuerdo 🙂
    • Tenga en cuenta que no va a funcionar si cualquiera de los objetos (etiquetas) en la matriz es una estructura circular, lo que significa que las referencias a sí mismo indirectamente. Ese caso va a terminar con «TypeError: la Conversión de una estructura circular a JSON» error.

  2. 4

    Como se mencionó Aquí .slice(0) será efectiva en la clonación de la matriz con un tipo primitivo de los elementos. Sin embargo, en su ejemplo tags matriz contiene los objetos anónimos. Por lo tanto cualquier cambio a estos objetos clonados matriz se refleja en tags matriz.

    @dangh la respuesta de arriba derefences de estos elementos los objetos y crear otros nuevos.

    Aquí hay otro hilo abordar situación similar

  3. 2

    Una buena manera de clonar a un array de objetos con ES6 es el uso de la propagación de la sintaxis:

    const clonedArray = [...oldArray];

    MDN

    • Esta es una copia superficial
  4. 1

    Usted sólo tiene que utilizar el ‘…’ notación.

    //THE FOLLOWING LINE COPIES all elements of 'tags' INTO 'copy'
    var copy = [...tags]

    Cuando se tiene una matriz decir x, […x] crea un nuevo array con todos los valores de x. Tenga cuidado, porque esta notación funciona de forma ligeramente diferente en los objetos. Divide los objetos en toda su clave, los pares de valores. Así que si quieres pasar todos los pares de valores de un objeto en una función sólo se necesita para pasar de la función({…obj})

    • Él necesita una copia profunda, no una copia superficial.
  5. 0

    Más fácil y optimista manera de hacer esto en una sola línea es el uso de Subrayado/Lodash

    sea a = _.mapa de b, _.clon)

  6. 0

    Mismo problema me pasa a mí. Tengo los datos de servicio y guardarlo en otra variable. Cuando cada vez que puedo actualizar mi matriz de la copia de la matriz también se actualiza. código viejo es como a continuación

    JS:

    //$scope.MyData get from service
    $scope.MyDataOriginal = $scope.MyData;

    Así que cuando alguna vez me cambio de $scope.MyData también de cambio de $scope.MyDataOriginal.
    He encontrado una solución que angulares.derecho de copia código abajo

    JS:

    $scope.MyDataOriginal = angular.copy($scope.MyData);

  7. 0

    Sé que esto es un poco más viejos post, pero tuve la buena fortuna de haber encontrado una manera decente para copia profunda matrices, incluso aquellos que contienen matrices, y los objetos, e incluso de los objetos que contienen las matrices se copian… solo puedo ver un problema con este código es que si usted no tiene suficiente memoria puedo ver esta ahogando en matrices muy grandes de arrays y objetos… Pero la mayor parte se debe trabajar. La razón por la que estoy publicando este de aquí es que se cumpla el OP solicitud de copia de la matriz de objetos por valor y no por referencia… así que ahora con el código (los controles son a partir de ENTONCES, la principal función de copia que yo misma escribí, no se de que otra persona probablemente no haya escrito antes, simplemente no estoy consciente de ellos)::

    var isArray = function(a){return (!!a) && (a.constructor===Array);}
    var isObject = function(a){return (!!a) && (a.constructor===Object);}
    Array.prototype.copy = function(){
        var newvals=[],
            self=this;
        for(var i = 0;i < self.length;i++){
            var e=self[i];
            if(isObject(e)){
                var tmp={},
                    oKeys=Object.keys(e);
                for(var x = 0;x < oKeys.length;x++){
                    var oks=oKeys[x];
                    if(isArray(e[oks])){
                        tmp[oks]=e[oks].copy();
                    } else { 
                        tmp[oks]=e[oks];
                    }
                }
                newvals.push(tmp);
            } else {
                if(isArray(e)){
                    newvals.push(e.copy());
                } else {
                    newvals.push(e);
                }
            }
        }
        return newvals;
    }

    Esta función (de la Matriz.el prototipo.copiar) utiliza la recursividad a remitir espontáneamente cuando un objeto o una matriz se denomina devolución de los valores según sea necesario. El proceso es decentemente rápido, y hace exactamente lo que se desea hacer, se hace una copia en profundidad de una matriz, por valor de… Probado en chrome, y IE11 y funciona en estos dos navegadores.

  8. -1

    Para esto yo uso el nuevo ECMAScript 6 Objeto.asignar método :

    let oldObject = [1,3,5,"test"];
    let newObject = Object.assign({}, oldObject)

    el primer argumento de este método es la matriz para ser actualizado,
    pasamos un objeto vacío porque queremos tener un objeto completamente nuevo,

    también puede agregar otros objetos para ser copiado demasiado :

    let newObject = Object.assign({}, oldObject, o2, o3, ...)
    • incluso con Objeto.asignar a tener los mismos problemas, cada método que existe ahora mismo en Javascript funciona bien con las primitivas, si usted tiene su objeto con las teclas que tienen como valor de otro objeto, las referencias serán guardados

Dejar respuesta

Please enter your comment!
Please enter your name here