2016-09-16 55 views
0

我正在使用Ramda构建一个简单的应用程序。在Ramda调用两次Arg

我遇到了一个功能组合问题,我不确定如何解决这个问题,而不是创建一个看似不必要的荒唐功能。

该场景:

我有一个对象作为参数传递。有此对象的两个属性,以及一些其他的东西,是不相关的比其他的问题,我想不会改变它的状态:

{locCode :<string>, LocationList : [<Location>], someOtherParams : ... } 

我有一个单一的ARG功能,它可以转换一个locCode的位置: fetchLocByCode

在这里,我需要的结果是采取了locCode值,将它传递给fetchLocByCode,结果追加LocationList,并返回新LocationList一个新的对象不接触物体上别的。

东西analagous到:

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

该解决方案“作品“,但似乎我错过了一些基本的想法。

有人会提出一个更“典型”的方式来解决这种情况?

回答

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。 ;)

+0

谢谢! 你的例子有助于提高这一点 - 为了保持“免费点”,忘记了直接访问某个属性仍然是完全可能的。 –