繁体   English   中英

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

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

我需要创建 function 通过合并有效负载 object 来更新列表中具有特定 ID 的项目

以 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
  )

我们当然可以在 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>

我们可以在输入 function 上将其读为mapwhen id属性等于 ( propEq ) 提供的id时,对payload和当前值执行mergeLeft when有一个隐含的理解,如果条件不匹配,它会原封不动地返回值。

如果您想要初始方法的完全无点版本,我们可以使用有点晦涩的useWith ,如下所示:

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

不过,我可能更喜欢这样写:

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

如果您想同时供应所有 arguments,我们可以这样做:

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

所有这些都假设我们正在测试每个元素。 它不假定id是唯一的。 如果你想这样做,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>

我们也可以在这个版本上转向无点,但我认为它最终会很丑陋。 我们可以使xs变得微不足道,但其他任何事情都会使其在我看来的可读性降低。

因此,首先我们要找到要更改的项目的索引:

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

如果那是-1,那么我们不需要做任何事情(返回项目)。 否则,我们必须通过将有效负载合并到该索引处的项目来调整项目。

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

最后我们只对 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