如何在Immutable js中删除Map中的数组元素?

时间:2017-06-30 14:20:58

标签: javascript immutable.js

我是Immutable的新手,我很担心如何删除Map中的数组元素。我不想使用fromJs。我知道Stack Overflow上有很多资源,但这对我不起作用。

const test = Map({
  arr: [{
    id: 1
  }, {
    id: 2
  }, {
    id: 3
  }]
});


console.log(test.get('arr'))

之前

arr:[{id:1},{id:2},{id:3}]

我想删除id:3

arr:[{id:1},{id:2}]

2 个答案:

答案 0 :(得分:1)

使用Immutable.js时,通常不应该使用Plain JS数据结构。因此,您可以创建以下数据:

test = Map({ arr: List([ Map({ id: 1 }), Map({ id: 2 }), Map({ id: 3 }) ]) })

并可以删除第三个对象,如下所示:

test.set('arr', test.get('arr').filter(x => x.get('id') != 3))

答案 1 :(得分:1)

这里的基本问题是,当您创建Map时,它只会将对象键浅转换为Map键。它没有深度转换对象。这没关系,但是你必须正确处理这个案例,当你第一次处理这种情况时可能会有点混乱。

首先,你应该明白这一点......

const test = Map({
  arr: [{
    id: 1
  }, {
    id: 2
  }, {
    id: 3
  }]
})

这是......

Map {
  arr: [
    { id: 1 },
    { id: 2 },
    { id: 3 }
  ]
}

存储在arr的值是一个数组而不是一个不可变的List,而存储在该数组中的值是对象而不是Maps。

要更改可变值,您需要更新Map并同时更改数组。请注意,您希望不可变地执行此操作,以便不更改存储在不可变映射中的可变值。这样做的不可变方式如下所示。

如果您知道具有id: 3的对象所在的索引,那么您可以切出该索引......

const i = 2
test = test  // remember that any change to an immutable object creates a new object, so assignment is required
  .update('arr', (arr) => {    
    return arr.slice(0, i).concat(arr.slice(i + 1))
  })

如果您不知道索引,那么您可以过滤数组...

test = test  // remember that any change to an immutable object creates a new object, so assignment is required
  .update('arr', (arr) => {    
    return arr.filter((obj) => obj.id !== 3)
  })

这种体验可能有点痛苦,所以我在处理混合嵌套数据结构时写了mudash来专门帮助。你可以用上面的方法实现同样的目的......

const _ = require('mudash')

// delete, this correctly traverses mixed structures...
test = _.delete(test, 'arr.2')

//update/filter, these methods correctly handle both immutable and stadard js types...
test = _.update(test, 'arr', (arr) => _.filter(arr, (obj) => obj.id !== 3))