我正在使用Ramda构建一个简单的应用程序。
我遇到了一个功能性构图问题,我不确定如何解决这个问题而不会创造一个看似不必要的荒谬功能。
情景:
我有一个对象作为参数传递。这个对象有两个属性,还有一些与问题无关的东西,除了我不想改变它的状态:
{locCode :<string>, LocationList : [<Location>], someOtherParams : ... }
我有一个arg函数可以将locCode转换为一个位置:
fetchLocByCode
我想要的结果是获取locCode
值,将其传递给fetchLocByCode
,将LocationList
附加到结果中,然后返回一个包含新LocationList
的新对象没有触及对象上的任何其他内容。
有点类似于:
(Param)=>{
Param.LocationList.push(fetchLocByCode(Param.locCode));
return Param;
}
我写完这篇文章似乎非常荒谬,让我相信自己做了一件可怕的错事:
const locListLens = R.lens(R.prop('LocationList'),R.assoc('LocationList'))
const appendLocList = (i)=>R.compose(R.over(locListLens),R.append,fetchLocByCode,R.prop('locCode'))(i)(i)
此解决方案的工作原理是&#39;但似乎我错过了一些基本的想法。
是否有人愿意提出更多的规范&#39;解决这种情况的方法是什么?
答案 0 :(得分:3)
让我们从您的初始版本开始:
Param => {
Param.LocationList.push(fetchLocByCode(Param.locCode));
return Param;
}
我非常希望不需要突变。我们将其删除:
Param =>
R.assoc('LocationList',
R.append(fetchLocByCode(Param.locCode), Param.LocationList),
Param)
我们可以使用镜头避免两次访问LocationList
属性:
Param =>
R.over(R.lensProp('LocationList'),
R.append(fetchLocByCode(Param.locCode)),
Param)
我们可以完全摆脱Param
吗?我们首先使用R.converge
:
R.converge(R.over(R.lensProp('LocationList')),
[Param => R.append(fetchLocByCode(Param.locCode)),
R.identity])
让我们使用R.compose
从第一个分支函数中删除Param
:
R.converge(R.over(R.lensProp('LocationList')),
[R.compose(R.append, fetchLocByCode, R.prop('locCode')),
R.identity])
每当你发现自己写R.converge(f, [g, R.identity])
时,你就发现了S
组合子的用途!
S.S(R.flip(R.over(R.lensProp('LocationList'))),
R.compose(R.append, fetchLocByCode, R.prop('locCode')))
虽然这很整洁,但我认为R.assoc
版本没问题。未来的读者不会喜欢理解S.S(R.flip(R.over(R.lensProp
。 ;)