Stack Overflow en español Asked by ABO172013923 on August 22, 2020
Realizo una iteración con ciclo for
, .push()
a un array nuevo. Sin embargo, al final de la iteración se repite el mismo registro.
var myArray = [
{ actividad: 'Work', valor: 9 },
{ actividad: 'Eat', valor: 1 },
{ actividad: 'Commute', valor: 2 },
{ actividad: 'Play Game', valor: 1 },
{ actividad: 'Sleep', valor: 7 }
];
console.log(myArray);
console.log(myArray.length);
var nuevoArray = [];
var registro = { actividad: '', valor: 0 }
for (var i = 0;i < myArray.length; i++) {
registro.actividad = myArray[i].actividad;
registro.valor = myArray[i].valor;
console.log(registro);
nuevoArray.push(registro);
}
console.log(nuevoArray);
console.log(nuevoArray.length);
Lo que pasa es que en Javascript (así como en muchos otros lenguajes alto nivel), el operador de asignación (=
) entre dos variable no asigna el valor de la variable derecha, si no su referencia a un espacio de memoria. Esto quiere decir que al cambiar cualquiera de las dos variables involucradas se cambiará el valor de ambas, debido a que ambas tienen como referencia la misma dirección de memoria.
Cada vez que defines a registro
reescribes su valor dentro del array y por fuera del array. Por eso mismo, solo permanece el último valor, debido a que ese fue el último cambio.
let arr = [{foo: 0,bar: 1},{foo: 2,bar: 3},{foo: 4,bar: 5}];
let copy = [];
let aux = {foo: 0,bar: 0};
for (let i = 0;i < arr.length;i++) {
aux.foo = arr[i].foo; /*Se reescribe foo de arr*/
aux.bar = arr[i].bar; /*Se reescribe bar de arr*/
copy.push(aux);
}
console.log(copy);
Tienes varias manera de evitar esto:
Si quieres tener una copia de los valores del array original puedes usar slice()
let arr = [{foo: 0,bar: 1},{foo: 2,bar: 3},{foo: 4,bar: 5}];
let copy = arr.slice(0,arr.length);
arr[0] = {foo: 6,bar: 7};
console.log(arr);
console.log(copy);
Sin embargo, los objetos del array van a seguir teniendo la referencia original. Si quieres hacer un deep copy puedes usar map()
.
let arr = [{foo: 0,bar: 1},{foo: 2,bar: 3},{foo: 4,bar: 5}];
let copy = arr.map((obj) => {
return {foo: obj.foo,bar: obj.bar};
});
arr[0].foo = 6;
arr[0].bar = 7;
console.log(arr);
console.log(copy);
Espero haberte ayudado.
Answered by Gabitohh on August 22, 2020
Al copiarlo de esa forma estás haciendo una copia POR REFERENCIA, es decir
al hacer nuevoArray.push(registro)
; estás apuntando registro nuevoArray a
registro, por ende cuando registro cambia, también va a cambiar los valores
que ingresaste en nuevoArray.
cámbialo por:
nuevoArray.push(JSON.parse(JSON.stringify(registro)));
Mira en el siguiente link: TrucoDeJson
"básicamente consiste en convertir un objeto en una cadena, copiar dicha cadena en la nueva variable, y reconvertir la cadena en objeto"
Answered by Byron2017 on August 22, 2020
si lo que queres es clonar un array, dejo 4 posibles formas de clonar y al final del código hago referencia a tú código y donde esta el problema.
var myArray = [
{actividad: 'Work', valor: 9},
{actividad: 'Eat', valor: 1},
{actividad: 'Commute', valor: 2},
{actividad: 'Play Game', valor: 1},
{actividad: 'Sleep', valor: 7}
];
var copia1 = myArray.slice();
var copia2 = [].concat(myArray);
var copia3 = [...myArray];
var copia4 = [];
Object.assign(copia4, myArray);
console.log("Copia 1")
console.log(copia1);
console.log("Copia 2")
console.log(copia2);
console.log("Copia 3")
console.log(copia3);
console.log("Copia 4")
console.log(copia4);
//TU CODIGO
var nuevoArray = [];
//SI DECLARAS ESTE OBJETO POR FUERA DEL FOR ESTAS USANDO LA MISMA REFERENCIA DEL OBJETO EN LA FUNCION PUSH DE ARRAY.
//var registro = { actividad: '', valor: 0 }
for (var i = 0;i < myArray.length; i++) {
//registro.actividad = myArray[i].actividad;
//registro.valor = myArray[i].valor;
//console.log(registro);
//CREAMOS NUEVO OBJETO CADA VEZ QUE INTERACTUA EL FOR.
var registro = { actividad: myArray[i].actividad, valor: myArray[i].valor };
//INSERTAMOS EL OBJETO.
nuevoArray.push(registro);
}
console.log("Copia 5")
console.log(nuevoArray);
En los ejemplos el contenido de los array son objetos (array de objetos) y estos se pasan como referencia no por copia, cuando le cambias la propiedad a uno este cambia en todos. Ejemplo: copia1.valor=1000 en copia2,copia3, copia4 van a cambiar el valor a 1000. En el ultimo ejemplo (tu código modificado) esta insertando al array un nuevo objeto que no esta referenciado con MyArray y las variables asignadas a los objetos como actividad (string) valor (numeric) estos se pasan por copia y no por referencia. Resumiendo el ultimo codigo de ejemplo generas una copia no referenciada. Resumiendo tú código para generar una copia full no referenciada:
var nuevoArray = [];
myArray.forEach(function (el) {
nuevoArray.push({actividad: el.actividad, valor: el.valor});
});
Answered by toto on August 22, 2020
Get help from others!
Recent Answers
Recent Questions
© 2024 TransWikia.com. All rights reserved. Sites we Love: PCI Database, UKBizDB, Menu Kuliner, Sharing RPP