简体   繁体   English

什么是完全 ramda.js 等效于此代码?

[英]What is fully ramda.js equivalent of this code?

i need create function that updates item with certain id in list by merging payload object我需要创建 function 通过合并有效负载 object 来更新列表中具有特定 ID 的项目

in ramda.js way以 ramda.js 的方式

export const updateItem = <T extends { id: I }, I>(items: T[], id: I, payload: Partial<T>) =>
  items.map(
    item => item.id === id
      ? ({ ...item, ...payload })
      : item
  )

We can certainly write a fairly readable version in Ramda:我们当然可以在 Ramda 中编写一个相当易读的版本:

 const updateItem = (id, payload) => map ( when (propEq ('id', id), mergeLeft (payload)) ) const items = [{foo: 'a', id: 1}, {foo: 'b', id: 2}, {foo: 'c', id: 1}, {foo: 'd', id: 4}] console.log (updateItem (1, {bar: 'x'}) (items)) // updates all with id of 1 console.log (updateItem (2, {bar: 'x'}) (items))
 .as-console-wrapper {max-height: 100%;important: top: 0}
 <script src="//cdnjs.cloudflare.com/ajax/libs/ramda/0.28.0/ramda.min.js"></script> <script> const {map, when, propEq, mergeLeft} = R </script>

We can read this as map over our input a function that when the id property equals ( propEq ) the id supplied, perform a mergeLeft on the payload and the current value.我们可以在输入 function 上将其读为mapwhen id属性等于 ( propEq ) 提供的id时,对payload和当前值执行mergeLeft when has an implicit understanding that if the condition doesn't match, it returns the value intact. when有一个隐含的理解,如果条件不匹配,它会原封不动地返回值。

If you want an entirely point-free version of the initial approach, we could use the somewhat obscure useWith , like this:如果您想要初始方法的完全无点版本,我们可以使用有点晦涩的useWith ,如下所示:

const updateItems = compose (map, useWith (when, [propEq ('id'), mergeLeft]))

I would probably prefer to write that like this, though:不过,我可能更喜欢这样写:

const updateItem = useWith (when, [propEq ('id'), mergeLeft])
const updateItems = compose (map, updateItem)

If you want to supply all arguments together, we could do this:如果您想同时供应所有 arguments,我们可以这样做:

const updateItem = (id, payload, xs) => 
  map (when (propEq ('id', id), mergeLeft (payload)), xs)
// ...
updateItem (1, {bar: 'x'}, items)

All of these make the assumption that we are testing every element.所有这些都假设我们正在测试每个元素。 It does not assume that the id is unique.它不假定id是唯一的。 If you want to do that, the answer from Chad S. would work, but I would prefer to do it slightly differently:如果你想这样做,Chad S. 的答案会起作用,但我更愿意稍微不同:

 const updateItems = (id, payload, xs) => adjust (findIndex (propEq ('id', id), xs), mergeLeft (payload), xs) const items = [{foo: 'a', id: 1}, {foo: 'b', id: 2}, {foo: 'c', id: 1}, {foo: 'd', id: 4}] console.log (updateItems (1, {bar: 'x'}, items)) // only the first one. console.log (updateItems (2, {bar: 'x'}, items))
 .as-console-wrapper {max-height: 100%;important: top: 0}
 <script src="//cdnjs.cloudflare.com/ajax/libs/ramda/0.28.0/ramda.min.js"></script> <script> const {adjust, findIndex, propEq, mergeLeft} = R </script>

We could also move toward point-free on this version, but I think it would end up pretty ugly.我们也可以在这个版本上转向无点,但我认为它最终会很丑陋。 We could make xs implicit trivially, but anything else would make it less readable to my mind.我们可以使xs变得微不足道,但其他任何事情都会使其在我看来的可读性降低。

So first we want to find the index of the item we want to change:因此,首先我们要找到要更改的项目的索引:

R.findIndex(R.propEq('id', id))

If that's -1 then we don't have to do anything (return the items).如果那是-1,那么我们不需要做任何事情(返回项目)。 Otherwise we have to adjust the items by merging the payload into the item at that index.否则,我们必须通过将有效负载合并到该索引处的项目来调整项目。

R.pipe(
  R.findIndex(R.propEq('id', id)), 
  R.ifElse(
    R.equals(-1), 
    R.always(R.identity), 
    R.adjust(R.__, R.mergeLeft(payload))
  )
)

Finally we just apply items to that pipe, and then apply items again to the result of the pipe:最后我们只对 pipe 应用项目,然后再次对 pipe 的结果应用项目:

const updateItem = R.curry((id, payload, items) => {
  return R.converge(R.applyTo, [
    R.identity,
    R.pipe(
      R.findIndex(R.propEq('id', id)), 
      R.ifElse(
        R.equals(-1), 
        R.always(R.identity), 
        R.adjust(R.__, R.mergeLeft(payload))
      )
    )
  ])(items)
});

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM