web-dev-qa-db-ja.com

変更せずにネストされたオブジェクトからデータを削除する

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

レデューサーは、IDを持つオブジェクトを含む配列と、次のようなオブジェクトを持つ別の配列です。

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

両方のIDを受け取り、ID abcのアイテムを削除する必要があります。

14
Daniel Storch

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
35
Dan Abramov
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'));
2
Ivan Nikitovic

私はこの方法で私の問題を解決しました

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

        return copy;
    }

それが他の誰かに役立つことを願っています。

0
Dante Cervantes

lodashの省略メソッド を使用することもできます。

Lodashをインポートすると、ビルドサイズがかなり大きくなることに注意してください。特定のメソッドだけをインポートして、ある程度チェックしてください:import omit from 'lodash/omit';

可能であれば、 ダンの答え で説明されているように、オブジェクト拡散演算子を使用することをお勧めします。

0
Antonio Merker

アンダースコアの拒否​​ を使用できます。それはあなたがやろうとしていることを正確に行います。

0
Cool Acid

プレーンな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
danielepolencic