¿Cómo puedo encontrar y actualizar valores en una matriz de objetos?

Resuelto user3712353 asked hace 8 años • 12 respuestas

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).

user3712353 avatar Feb 04 '16 23:02 user3712353
Aceptado

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;
    }
});
CodingIntrigue avatar Feb 04 '2016 16:02 CodingIntrigue

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 listcomo 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 listlargo 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.

Soldeplata Saketos avatar Jun 15 '2017 09:06 Soldeplata Saketos

Una línea usando el operador de extensión.

 const updatedData = originalData.map(x => (x.id === id ? { ...x, updatedField: 1 } : x));
tonymayoral avatar Apr 19 '2020 12:04 tonymayoral

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
Toodoo avatar Jan 31 '2018 14:01 Toodoo

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)
Fellow Stranger avatar Nov 21 '2019 16:11 Fellow Stranger