Ramda.js:组合函数时如何传递同一参数以简化Map操作
问题分析与解决方案
你的原始代码通过展开对象并重新计算sth属性来更新数组中的每个对象,而你尝试的compose写法之所以不生效,核心问题在于:R.assoc('sth')需要三个参数——键名、新值、源对象,但你的compose链只把过滤后的sth值传给了assoc,丢失了原对象这个关键参数(assoc需要它来创建新的对象副本)。
最简洁的写法:用R.evolve
其实Ramda专门提供了R.evolve来处理这种对对象指定属性应用变换的场景,它会自动帮你保留原对象的其他属性,只更新目标属性:
R.map( R.evolve({ sth: R.filter(R.propEq('key', val)) }), array )
这个写法完全符合你的需求:不需要传递字面量函数,直接用Ramda的组合函数完成逻辑——evolve接收一个配置对象,指定要对sth属性应用R.filter(R.propEq('key', val))这个变换,最终返回更新后的对象。
如果你坚持用R.assoc:用R.converge
如果一定要通过R.assoc来实现,我们可以用R.converge来解决「需要同时把原对象传给两个不同函数」的问题。converge会将同一个输入传递给多个函数,再把这些函数的结果汇总到目标函数中:
R.map( R.converge(R.assoc('sth'), [ // 第一个函数:计算新的sth值 R.compose(R.filter(R.propEq('key', val)), R.prop('sth')), // 第二个函数:直接返回原对象(作为assoc的第三个参数) R.identity ]), array )
这里converge把每个对象同时传给两个函数:一个负责生成新的sth值,另一个返回原对象;然后这两个结果会作为参数传给R.assoc('sth'),相当于执行R.assoc('sth', 新sth值, 原对象),最终得到更新后的对象。
内容的提问来源于stack exchange,提问作者Cragmorton
相关产品推荐
相关产品推荐

