14

是否有任何优雅的方法可以从作为数组一部分的数组中删除对象?我已经使用 React 和 Redux 有一段时间了,但是每次我必须在不改变状态的情况下删除或插入数据时都会卡住几个小时。

reducer 是一个包含具有 ID 的对象的数组和另一个包含对象的数组,如下所示:

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

我收到了两个 ID,需要删除带有 ID 的项目abc

4

6 回答 6

35

按 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
于 2016-02-27T22:07:24.073 回答
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'));
于 2017-09-21T09:23:40.957 回答
0

您可以使用下划线的拒绝。它完全符合您的要求。

于 2016-02-12T16:45:54.400 回答
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');
于 2016-02-12T21:13:28.343 回答
0

你也可以使用lodash 的 omit 方法

请注意,导入 lodash 会大大增加您的构建大小。通过仅导入特定方法来对其进行检查: import omit from 'lodash/omit';

如果可能的话,我建议使用Dan's answer中描述的对象扩展运算符。

于 2016-11-21T08:27:30.660 回答
0

我以这种方式解决了我的问题

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

        return copy;
    }

希望它对其他人有帮助。

于 2016-11-23T20:54:00.143 回答