嵌套列表过滤&与Ramda的条件对象映射

时间:2018-06-08 18:16:12

标签: javascript arrays ramda.js

我试图把头包裹在Ramda.js身边但是我被卡住了。我有一个看起来像这样的数组:

removeAnimation(121, 2, state);

我的目标是创建一个

的功能
const state = [
  {
    itemId: 112,
    animations: [{id: 1}, {id:2}],
    classes: ['animated']    
  },
  {
    itemId: 121,
    animations: [],
    classes: []    
  }
]

......会回来:

id

因此该函数根据具有指定itemId的对象内的指定animations删除动画obj,如果animated数组中不再存在对象,则它也会删除classes列表中的const removeAnimationFromItem = R.curry((itemId, animId, state) => { return R.map( R.when( R.propEq('itemId', itemId), [--This is where I'm stuck--] ), state) }) 字符串。

这是我走了多远:

{{1}}

感谢您的时间。

1 个答案:

答案 0 :(得分:1)

我认为这里有一个重要的问题,你是否真的想要Ramda的行为。如果我们使用Ramda执行类似的操作,它将不会更改您的数据。它将返回与原始文件共享内容的新对象,但您的原件仍将保持原样。 Ramda团队(免责声明:我是Ramda的一位作者)认为这是一件非常好的事情。但有时它可能会令人惊讶。

Ramda没有任何现成的解决方案可以让这很容易。如果我这样做,我可能会先将其分解为两个步骤:删除目标动画,然后更新所有项目的classes属性。我觉得这个更容易思考。如果结果出现性能问题,我可能会将它们结合起来。

这是一种方法:

const {findIndex, propEq, adjust, evolve, remove, without, pipe, map} = R

const removeOneAnimation = (itemId, animId, state) => {
  const itemIdx = findIndex(propEq('itemId', itemId), state)
  if (itemIdx < 0) {return state}
  const animIdx = findIndex(propEq('id', animId), state[itemIdx].animations)
  if (animIdx < 0) {return state}
  return adjust(evolve({animations: remove(animIdx, 1)}) , itemIdx, state)
}

const updateAnimClass = (item) => item.animations.length === 0 ? evolve({classes: without(['animated'])}, item) : item

const removeAnimations = pipe(
  removeOneAnimation,
  map(updateAnimClass)
)

const state = [{"animations": [{"id": 1}, {"id": 2}], "classes": ["animated"], "itemId": 112}, {"animations": [{"id": 2}], "classes": ["animated"], "itemId": 121}]

const newState = removeAnimations(121, 2, state)

console.log(newState)
<script src="//cdnjs.cloudflare.com/ajax/libs/ramda/0.25.0/ramda.js"></script>

请注意,这里的一些Ramda代码并没有给出很大的提升。例如,这个:

  const itemIndex = findIndex(propEq('itemId', itemId), state)

可以很容易地写成

  const itemIndex = state.findIndex(item => item.itemId === itemId)

但是其他一些功能,例如evolveadjustremovewithout做了很多。如果你想让Ramda将数据视为不可变的方法,那么它们就相当强大。