2016-02-11 18 views
13

配列の一部であるオブジェクトからオブジェクトを削除する方法はありますか? 私はしばらくの間ReactとReduxで作業していましたが、状態を変更することなくデータを削除または挿入する必要があるたびに、数時間かかることがありました。ネストされたオブジェクトからデータを変更せずに削除する

減速は、IDと、このようなオブジェクトと別の配列を有するオブジェクトを含む配列である:

[ 
{ id:123, 
    items:[ 
      { id: abc, 
      name: albert 
      }, 
      ... 
     ] 
}, 
... 
] 

Iの両方のIDを受信し、ID abcでアイテムを削除する必要があります。

+1

あなたはこれを読んで、あなたの状態の構造を再検討すべきです。 http://stackoverflow.com/questions/32135779/updating-nested-data-in-redux-store/32921731#32921731 – larrydahooster

+0

完全な複雑な配列をレジューサーに渡す代わりに、配列の項目を受け取る新しいレデューサーを作成します変更を行う状態として –

+0

まあ、それもやっている方法。しかし、私はid:123のオブジェクトの項目が必要なたびに、私はdemを "検索"する必要があります。 もう1つの質問ですが、バックエンドからJSONを受け取ったとき、どうやっていくつかのレデューサーに分割しますか?フェッチは、1つの減速機に行くよりもむしろ実行されます。 –

答えて

28

IDによって配列から項目を削除するには:

return state.filter(item => item.id !== action.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 

(ボーナス)と同じ:

は、IDによってオブジェクトからキーを削除しますobject spread operator proposal

let { [action.id]: deletedItem, ...rest } = state 
return rest 
+0

それらの組み合わせは、私が使い終わったものです。 –

+0

最後の例で 'deletedItem'は/ do/mean/containsを何にしますか? – Mbrevda

+0

@Mbrevda 'deletedItem'は削除された項目(' action.id'に割り当てられた項目)に割り当てられた変数名です。状態を2つの新しいオブジェクトに変えています.1つは拒否されたアイテム、もう1つは残りのアイテムです。 –

0

Underscore's rejectを使用できます。あなたがしようとしていることを正確に行います。

+0

配列ではないオブジェクトを返します。 – Sassan

0

あなたは、プレーン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'); 
0

lodash's omit methodも使用できます。

lodashをインポートすると、ビルドサイズがかなり増加することに注意してください。可能であれば、Dan's answerに記載されているオブジェクトスプレッド演算子を使用することをお勧めします。

0

私は

if(action.type === "REMOVE_FROM_PLAYLIST"){ 
     let copy = Object.assign({}, state) 
     delete copy.playlist[action.index].songs[action.indexSongs]; 

     return copy; 
    } 

このように私の問題を解決するには、それが他のいずれかのに役立ちます願っています。

2
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')); 
関連する問題