オブジェクトの配列があります。いくつかのフィールドで検索し、それを変更したい:
var item = {...}
var items = [{id:2}, {id:2}, {id:2}];
var foundItem = items.find(x => x.id == item.id);
foundItem = item;
元のオブジェクトを変更したい。どうやって?(それがロダッシュでもかまいません)
オブジェクトの配列があります。いくつかのフィールドで検索し、それを変更したい:
var item = {...}
var items = [{id:2}, {id:2}, {id:2}];
var foundItem = items.find(x => x.id == item.id);
foundItem = item;
元のオブジェクトを変更したい。どうやって?(それがロダッシュでもかまいません)
回答:
findIndexを使用して、オブジェクトの配列内のインデックスを検索し、必要に応じて置き換えることができます。
var item = {...}
var items = [{id:2}, {id:2}, {id:2}];
var foundIndex = items.findIndex(x => x.id == item.id);
items[foundIndex] = item;
これは一意のIDを想定しています。(例のように)IDが重複している場合は、forEachを使用した方がよいでしょう。
items.forEach((element, index) => {
if(element.id === item.id) {
items[index] = item;
}
});
let
代わりにキーワードを使用した方がよい場合がありますvar
map
ます。何が起こっているのかを理解するために必要なより少ない精神体操。余分なコード行の価値があります。
私の最善のアプローチは:
var item = {...}
var items = [{id:2}, {id:2}, {id:2}];
items[items.findIndex(el => el.id === item.id)] = item;
findIndexのリファレンス
また、新しいオブジェクトに置き換えたくない場合は、代わりにのフィールドをコピーするにはitem
、次のように使用できますObject.assign
。
Object.assign(items[items.findIndex(el => el.id === item.id)], item)
の代替として.map()
:
Object.assign(items, items.map(el => el.id === item.id? item : el))
配列を変更せず、新しい配列を使用して、副作用を発生させない
const updatedItems = items.map(el => el.id === item.id ? item : el)
try/catch
、要素を見つけられないことは例外的なケースではないため、ラップしないでください。これは、戻り値を確認しfindIndex
、要素が見つかった場合にのみ配列を更新することで説明する必要がある標準的なケースです。
別のアプローチは、スプライスを使用することです。
この
splice()
メソッドは、既存の要素を削除または置換したり、新しい要素を適切な場所に追加したりして、配列の内容を変更します。
注意:リアクティブフレームワークを使用している場合は、「ビュー」が更新され、配列は更新したことを「認識」します。
答え:
var item = {...}
var items = [{id:2}, {id:2}, {id:2}];
let foundIndex = items.findIndex(element => element.id === item.id)
items.splice(foundIndex, 1, item)
また、アイテムの値のみを変更する場合は、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
変更されたオブジェクトと配列が与えられた場合:
const item = {...}
let items = [{id:2}, {id:3}, {id:4}];
配列を反復処理して、配列を新しいオブジェクトで更新します。
items = items.map(x => (x.id === item.id) ? item : x)
const list = [{id:0}, {id:1}, {id:2}];
let listCopy = [...list];
let filteredDataSource = listCopy.filter((item) => {
if (item.id === 1) {
item.id = 12345;
}
return item;
});
console.log(filteredDataSource);
配列[オブジェクト{id:0}、オブジェクト{id:12345}、オブジェクト{id:2}]
私のために働いた
let returnPayments = [ ...this.payments ];
returnPayments[this.payments.findIndex(x => x.id == this.payment.id)] = this.payment;
既存の回答のほとんどはすばらしいものですが、ここでも考慮すべき従来のforループを使用した回答を含めたいと思います。OPはES5 / ES6互換の回答を要求し、従来のforループが適用されます:)
このシナリオで配列関数を使用する場合の問題は、オブジェクトを変更しないことですが、この場合、変更が必須です。従来のforループを使用することによるパフォーマンスの向上は、(大きな)ボーナスにすぎません。
const findThis = 2;
const items = [{id:1, ...}, {id:2, ...}, {id:3, ...}];
for (let i = 0, l = items.length; i < l; ++i) {
if (items[i].id === findThis) {
items[i].iAmChanged = true;
break;
}
}
私は配列関数の大ファンですが、それらをツールボックスの唯一のツールにしないでください。目的が配列の変更である場合、それらは最適ではありません。
item
にid
キーが含まれていますか?またはitem
、配列のエントリにオブジェクトのIDとすべてのプロパティがあることを気にしますか?