2016-09-16 57 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

謝謝! 你的例子有助於提高這一點 - 爲了保持「免費點」,忘記了直接訪問某個屬性仍然是完全可能的。 –