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

Javascript 如何从Immutable中的数组中删除对象?,javascript,immutable.js,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 = {
  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

的有效值

或者,当您正在“搜索然后删除”


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

在寻找类似任务的解决方案时发现此线程。 用以下方法解决:


有什么想法/评论哪一个更好/更喜欢?

当你使用过滤器时,它会重复所有的循环->一个有效的方法是找到index=>slice并使用splitter

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

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

即使不使用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
}
函数数组过滤器(数组,过滤器){
设ret=array
设为0
for(让index=0;index
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之前进行)。

非常简单-我显然太难使用Immutable的方法:)谢谢!有一个警告,这将始终返回一个新的不可变,即使数组没有匹配的元素。根据结构的大小,这可能是值得知道的,因为它将有效地击败任何基于React中不可变状态比较进行的渲染优化。。。任何帮助!!我喜欢这个!!!比循环和拼接容易多了,我再也不会这样做了。我认为这是错误的。它不应该被设置和获取吗。例如,state.setIn('things',state.getIn('things').filter(o=>o.get('id')!='a1')<代码>状态.update('things',things=>things.filter(things=>things.get('id')!='a2')这是否回答了您的问题?
const index = state.findIndex(data => data.id === action.id);

return [...state.slice(0, index), ...state.slice(index + 1)];
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
}
// 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 } }})