配列の一部である配列からオブジェクトを削除するエレガントな方法はありますか?私はしばらくの間ReactとReduxを使用していますが、状態を変更せずにデータを削除または挿入する必要があるたびに数時間スタックします。
レデューサーは、IDを持つオブジェクトを含む配列と、次のようなオブジェクトを持つ別の配列です。
[
{ id:123,
items:[
{ id: abc,
name: albert
},
...
]
},
...
]
両方のIDを受け取り、ID abc
のアイテムを削除する必要があります。
Idで配列からアイテムを削除するには:
return state.filter(item => item.id !== action.id)
IDでオブジェクトからキーを削除するには:
let copy = Object.assign({}, state) // assuming you use Object.assign() polyfill!
delete copy[action.id] // shallowly mutating a shallow copy is fine
return copy
(ボーナス) オブジェクトスプレッド演算子の提案 と同じ:
let { [action.id]: deletedItem, ...rest } = state
return rest
const remove = (state, bucketId, personId) => state.map(
bucket => bucket.id === bucketId
? { ...bucket, items: bucket.items.filter(person => person.id !== personId) }
: bucket,
);
使用法:
const state = [
{
id: 123,
items: [
{
id: 'abc',
name: 'Kinna',
},
{
id: 'def',
name: 'Meggy',
},
],
},
{
id: 456,
items: [
{
id: 'ghi',
name: 'Ade',
},
{
id: 'jkl',
name: 'Tades',
},
],
},
];
console.log(remove(state, 123, 'abc'));
私はこの方法で私の問題を解決しました
if(action.type === "REMOVE_FROM_PLAYLIST"){
let copy = Object.assign({}, state)
delete copy.playlist[action.index].songs[action.indexSongs];
return copy;
}
それが他の誰かに役立つことを願っています。
lodashの省略メソッド を使用することもできます。
Lodashをインポートすると、ビルドサイズがかなり大きくなることに注意してください。特定のメソッドだけをインポートして、ある程度チェックしてください:import omit from 'lodash/omit';
可能であれば、 ダンの答え で説明されているように、オブジェクト拡散演算子を使用することをお勧めします。
アンダースコアの拒否 を使用できます。それはあなたがやろうとしていることを正確に行います。
プレーンなJavascriptを選択する場合、私が考えることができる最もエレガントな方法は、Array.prototype.reduce
を使用して状態を減らすことです。
var state = [
{ id: 123,
items:[
{ id: 'abc',
name: 'albert'
},
...
]
},
...
]
function filterOut (state) {
return (bucketId, personId) => {
return state.reduce((state, bucket) => {
return state.concat(
(bucketId === bucket.id) ?
Object.assign({}, bucket, {items: bucket.items.filter((person) => person.id !== personId)}) :
bucket
);
}, []);
}
}
var newState = filterOut(state)(123, 'abc');