¿Cómo puedo encontrar y actualizar valores en una matriz de objetos?
Tengo una variedad de objetos. Quiero buscar por algún campo y luego cambiarlo:
var item = {...}
var items = [{id:2}, {id:2}, {id:2}];
var foundItem = items.find(x => x.id == item.id);
foundItem = item;
Quiero que cambie el objeto original. ¿Cómo? (No me importa si también estará en Lodash).
Puede usar findIndex para buscar el índice en la matriz del objeto y reemplazarlo según sea necesario:
var item = {...}
var items = [{id:2}, {id:2}, {id:2}];
var foundIndex = items.findIndex(x => x.id == item.id);
items[foundIndex] = item;
Esto supone identificaciones únicas. Si sus ID están duplicados (como en su ejemplo), probablemente sea mejor si usa forEach:
items.forEach((element, index) => {
if(element.id === item.id) {
items[index] = item;
}
});
Mi mejor enfoque es:
var item = {...}
var items = [{id:2}, {id:2}, {id:2}];
items[items.findIndex(el => el.id === item.id)] = item;
Referencia para findIndex
Y en caso de que no desee reemplazar con un nuevo objeto, sino copiar los campos de item
, puede usar Object.assign
:
Object.assign(items[items.findIndex(el => el.id === item.id)], item)
como alternativa con .map()
:
Object.assign(items, items.map(el => el.id === item.id? item : el))
Enfoque funcional :
No modifiques el array, usa uno nuevo, para no generar efectos secundarios
const updatedItems = items.map(el => el.id === item.id ? item : el)
Nota
Si se usan correctamente, las referencias a objetos no se pierden, por lo que incluso podría usar la referencia del objeto original, en lugar de crear otras nuevas.
const myArr = [{ id: 1 }, { id: 2 }, { id: 9 }];
const [a, b, c] = myArr;
// modify original reference will change object in the array
a.color = 'green';
console.log(myArr[0].color); // outputs 'green'
Este problema suele ocurrir cuando se consumen listas de la base de datos y luego se asigna la lista para generar contenido HTML que modificará los elementos de la lista, y luego necesitamos actualizar la lista y enviarla de regreso a la base de datos como una lista.
La buena noticia es que las referencias se conservan, por lo que puedes organizar tu código para aprovecharlo y considerarlo list
como un objeto con identidades de forma gratuita, que son números enteros del 0 al length -1
. Entonces, cada vez que acceda a cualquier propiedad de su Objeto, hágalo como list[i]
y no perderá la referencia y el objeto original cambiará. Tenga en cuenta que esto es útil cuando su fuente de verdad es solo una (el Objeto creado) y su aplicación siempre consume consistentemente el mismo Objeto (sin buscarlo varias veces de la base de datos y asignarlo a lo list
largo de la vida útil del componente).
La mala noticia es que la arquitectura es incorrecta y debería recibir un objeto por identificadores (diccionario) si esto es lo que necesita, algo como
{
1232: { id: 1232, ...},
asdf234asf: { id: 'asdf234asf', ...},
...
}
De esta manera, no busca en matrices, lo que consume recursos. Usted "simplemente accede mediante la clave en el objeto", que es instantáneo y eficaz.
Una línea usando el operador de extensión.
const updatedData = originalData.map(x => (x.id === id ? { ...x, updatedField: 1 } : x));
Otro enfoque es utilizar empalme .
El
splice()
método cambia el contenido de una matriz eliminando o reemplazando elementos existentes y/o agregando nuevos elementos en su lugar .
NB: en caso de que esté trabajando con marcos reactivos, actualizará la "vista", su matriz "sabiendo" que la ha actualizado.
Respuesta :
var item = {...}
var items = [{id:2}, {id:2}, {id:2}];
let foundIndex = items.findIndex(element => element.id === item.id)
items.splice(foundIndex, 1, item)
Y en caso de que solo desee cambiar el valor de un elemento, puede usar la función de búsqueda :
// Retrieve item and assign ref to updatedItem
let updatedItem = items.find((element) => { return element.id === item.id })
// Modify object property
updatedItem.aProp = ds.aProp
Dado un objeto modificado y una matriz:
const item = {...}
let items = [{id:2}, {id:3}, {id:4}];
Actualice la matriz con el nuevo objeto iterando sobre la matriz:
items = items.map(x => (x.id === item.id) ? item : x)