Javascript 如何从不可变的数组中删除对象?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/36761056/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-23 19:31:43  来源:igfitidea点击:

How to remove an object from an array in Immutable?

javascriptimmutable.js

提问by ffxsam

Given a state like this:

给定这样的状态:

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

How can I create a new state where ID "a1" is removed? It's easy enough to push new items:

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

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

But I can't figure out how to search for and remove an object by its idproperty. I tried this:

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

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

But it seems messy, plus it only works if the item is found, because if findIndexreturns -1, that's a valid value for delete.

但它看起来很乱,而且它仅在找到该项目时才有效,因为如果findIndex返回-1,则这是 的有效值delete

回答by Tushar

You can use Array#filter.

您可以使用Array#filter.

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

回答by Musa

When you are using filter it iterates all cycle -> one effective way is finding index => slice and using splitter ...

当您使用过滤器时,它会迭代所有周期 -> 一种有效的方法是查找索引 => 切片并使用拆分器 ...

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

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

回答by hazardous

Alternatively, as you are "searching and then deleting"...

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

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

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

This will ensure the state is not mutated when there are no changes.

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

回答by Roman Krayovskyy

Found this thread while looking for a solution to a similar task. Solved it with updatemethod:

在寻找类似任务的解决方案时发现了这个线程。用更新方法解决了它:

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

any idea/comment which one is better/preferred?

任何想法/评论哪个更好/更喜欢?

回答by pravdomil

You can do that even without immutable.js with following function.

即使没有具有以下功能的 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
}

回答by Jason Sebring

ImmutableJS working with nested arrays

ImmutableJS 处理嵌套数组

Immutablejs is great but at the same time makes things more complicated in some edge cases, particularly when working with nested arrays.

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

Sometimes it is easier to take it back to JS in a general sense for this particular issue.

对于这个特定问题,有时更容易将其带回一般意义上的 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 } }})

Unfortunately, step 3 is necessary to specifically set to undefinedbecause if you simply set myListdirectly as an array value, ImmutableJS will do a comparison of values between the current list and only modify them creating strange behavior.

不幸的是,步骤 3 需要专门设置为,undefined因为如果您只是myList直接设置为数组值,ImmutableJS 将在当前列表之间进行值的比较,并且只会修改它们,从而产生奇怪的行为。

The justification for this is to simplify the mental overhead.I do not recommend doing this in a loop, rather manipulate the pure JS array in a loop if you must but should be prior to step 3.

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