javascript - Cum pot găsi și actualiza valorile dintr-un array de obiecte?
Am un array de obiecte. Vreau să caut după un anumit câmp și apoi să-l schimb:
var item = {...}
var items = [{id:2}, {id:2}, {id:2}];
var foundItem = items.find(x => x.id == item.id);
foundItem = item;
Vreau să schimbe obiectul original. Cum? (Nu-mi pasă dacă va fi și în Lodash.)
Răspuns #1
Poți folosi findIndex pentru a găsi indexul în array al obiectului și a-l înlocui după cum este necesar:
var item = {...}
var items = [{id:2}, {id:2}, {id:2}];
var foundIndex = items.findIndex(x => x.id == item.id);
items[foundIndex] = item;
Acest lucru presupune ID-uri unice. Dacă ID-urile tale sunt duplicate (așa cum este în exemplul tău), probabil este mai bine să folosești forEach:
items.forEach((element, index) => {
if(element.id === item.id) {
items[index] = item;
}
});
Răspunsul #2
Cea mai bună abordare a mea este:
var item = {...}
var items = [{id:2}, {id:2}, {id:2}];
items[items.findIndex(el => el.id === item.id)] = item;
Referință pentru findIndex
Și în cazul în care nu doriți să înlocuiți cu un obiect nou, ci să copiați câmpurile lui item, puteți folosi Object.assign:
Object.assign(items[items.findIndex(el => el.id === item.id)], item)ca alternativă cu .map():
Object.assign(items, items.map(el => el.id === item.id? item : el))Abordare funcțională:
Nu modificați array-ul, folosiți unul nou, astfel încât să nu generați efecte secundare
const updatedItems = items.map(el => el.id === item.id ? item : el)
Notiță
Folosite corect, referințele la obiecte nu se pierd, așa că ai putea chiar folosi referința originală la obiect, în loc să creezi altele noi.
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'
Această problemă apare de obicei atunci când se consumă liste din baza de date și apoi se mapează lista pentru a genera conținut HTML, ceea ce va modifica elementele listei, și apoi trebuie să actualizăm lista și să o trimitem înapoi la baza de date ca o listă.
Veștile bune sunt că referințele sunt păstrate, așa că poți organiza codul tău pentru a profita de asta și să te gândești la un list ca la un Obiect cu identități gratuite, care sunt numere întregi de la 0 la length -1. Așadar, de fiecare dată când accesezi orice proprietate a Obiectului tău, fă-o ca list[i], și nu pierzi referința, iar obiectul original este modificat. Ține minte că acest lucru este util atunci când sursa ta de adevăr este doar una (Obiectul creat), și aplicația ta consumă întotdeauna în mod constant același Obiect (nu îl preia de mai multe ori din baza de date și îl atribuie la list pe parcursul duratei de viață a componentului).
Vestea proastă este că arhitectura este greșită și ar trebui să primești un obiect prin id-uri (dicționar) dacă asta ai nevoie, ceva de genul
{
1232: { id: 1232, ...},
asdf234asf: { id: 'asdf234asf', ...},
...
}
Astfel, nu cauți în array-uri, ceea ce consumă resurse. "Pur și simplu accesezi prin cheie în obiect", ceea ce este instantaneu și performant.
Răspunsul #3
O linie folosind operatorul spread.
const updatedData = originalData.map(x => (x.id === id ? { ...x, updatedField: 1 } : x));
Răspunsul #4
O altă abordare este să folosești splice.
Metoda
splice()schimbă conținutul unui array prin eliminarea sau înlocuirea elementelor existente și/sau adăugarea de elemente noi pe loc.
N.B : În cazul în care lucrați cu framework-uri reactive, acesta va actualiza „vederea”, iar array-ul vostru „știind” că l-ați actualizat.
Răspuns :
var item = {...}
var items = [{id:2}, {id:2}, {id:2}];
let foundIndex = items.findIndex(element => element.id === item.id)
items.splice(foundIndex, 1, item)
Și în cazul în care vrei să schimbi doar valoarea unui element, poți folosi funcția find :
// Retrieve item and assign ref to updatedItem
let updatedItem = items.find((element) => { return element.id === item.id })
// Modify object property
updatedItem.aProp = ds.aProp
Răspunsul #5
Având un obiect modificat și un array:
const item = {...}
let items = [{id:2}, {id:3}, {id:4}];
Actualizează matricea cu noul obiect parcurgând matricea:
items = items.map(x => (x.id === item.id) ? item : x)
