[英]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 上将其读为map
, when
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.