如何从Immutable中的数组中删除对象?

时间:2016-04-21 06:13:28

标签: javascript immutable.js

鉴于这样的状态:

state = {
  things: [
    { id: 'a1', name: 'thing 1' },
    { id: 'a2', name: 'thing 2' },
  ],
};

如何创建删除ID“a1”的新状态?推送新商品很容易:

return state.set(state.get('things').push(newThing));

但我无法弄清楚如何通过id属性搜索和删除对象。我试过这个:

return state.set('tracks',
  state.get('tracks').delete(
    state.get('tracks').findIndex(x => x.get('id') === 'a2')
  )
)

但它看起来很混乱,而且只有在找到项目时它才有效,因为如果findIndex返回-1,那就是delete的有效值。

6 个答案:

答案 0 :(得分:31)

您可以使用Array#filter

return state.set('things', state.get('things').filter(o => o.get('id') !== 'a1'));

答案 1 :(得分:10)

当您使用过滤器时,它会迭代所有循环 - >一种有效的方法是找到index =>切片和使用分离器...

const index = state.findIndex(data => data.id === action.id);

return [...state.slice(0, index), ...state.slice(index + 1)];

答案 2 :(得分:3)

或者,当您“搜索然后删除”时......

var itemIndex = this.state.get("tracks").findIndex(x => x.get('id') === 'a2');

return itemIndex > -1 ? this.state.deleteIn(["tracks", itemIndex]) : this.state;

这将确保在没有变化时状态不会发生变异。

答案 3 :(得分:0)

在寻找类似任务的解决方案时找到此线程。 使用update方法解决了这个问题:

return state.update('things', (things) => things.filter((t) => t.id !== action.things.id))

任何一个更好/首选的想法/评论?

答案 4 :(得分:0)

即使没有带有以下功能的immutable.js,你也可以这样做。

function arrayFilter(array, filter) {
  let ret = array
  let removed = 0
  for (let index = 0; index < array.length; index++) {
    const passed = filter(array[index], index, array)
    if (!passed) {
      ret = [...ret.slice(0, index - removed), ...ret.slice(index - removed + 1)]
      removed++
    }
  }
  return ret
}

答案 5 :(得分:0)

ImmutableJS使用嵌套数组

Immutablejs很棒,但同时在某些边缘情况下使事情变得更复杂,特别是在使用嵌套数组时

对于这个特定的问题,有时候一般意义上更容易将它带回JS。

// 1. get a copy of the list into normal JavaScript
const myList = state.getIn(['root', 'someMap', 'myList']).toJS()

// 2. remove item in list using normal JavaScript and/or anything else
myList.splice(deleteIndex, 1)

// 3. return the new state based on mutated myList
return state
  .mergeDeep({ root: { someMap: { myList: undefined } }})
  .mergeDeep({ root: { someMap: { myList } }})

不幸的是,第3步是专门设置为undefined所必需的,因为如果您只是将myList直接设置为数组值,则ImmutableJS将对当前列表之间的值进行比较,并仅修改它们奇怪的行为。

这样做的理由是简化心理开销。我不建议在循环中执行此操作,而是在循环中操作纯JS数组(如果必须但是应该在第3步之前)