若想將 Array 中一系列 Function 套用到另一 Array,Ramda 並沒有提供適當 Function,我們可自行組合出 zipFunc()
。
Version
macOS Mojave 10.15.2
VS Code 1.41.1
Quokka 1.0.271
Ramda 0.26.1
Wink-fp 1.20.44
Imperative
import { inc, dec, negate } from 'ramda'
let data1 = [inc, dec, negate]
let data2 = [1, 2, 3]
let zipFunc = fns => arr => {
let result = []
for (let i = 0; i < arr.length; i++) {
result[i] = fns[i](arr[i])
}
return result
}
zipFunc(data1)(data2) // ?
data1
有一系列 function,會依序套用到 data2
array。
inc()
、dec()
與 negate()
只是借用 Ramda 的 function,這不是重點,你也可以使用自己的 function。
Imperative 會使用 for
loop 並搭配 i
變數,同時套用 args
與 arr
兩個 array。
Array.prototype.reduce()
import { inc, dec, negate } from 'ramda'
let data1 = [inc, dec, negate]
let data2 = [1, 2, 3]
let zipFunc = fns => arr => arr.reduce((a, x, i) => [...a, fns[i](x)], [])
zipFunc(data1)(data2) // ?
for
loop 也可使用 Array.prototype.reduce()
改寫。
Ramda
import { zipWith, call, inc, dec, negate } from 'ramda'
let data1 = [inc, dec, negate]
let data2 = [1, 2, 3]
let zipFunc = zipWith(call)
zipFunc(data1)(data2) // ?
Ramda 並沒有提供 zipFunc()
,但我們可以自行組合。
由於要將兩個 array 配對合併成新 array,因此會想到 Ramda 的 zip
系列,該系列共有 zip()
、zipWith()
與 zipObj()
,其中 zipObj()
結果為 object,因此不予考慮,而 zip()
又過於制式,也無法使用,最後只剩下 zipWith()
。
zipWith()
原意是要我們傳入兩個 array 經過 callback 運算,但有趣的是目前 function 已經在 array 中了,根本不需要 callback,所以 callback 只剩下一個目的:執行 array 中的 function。
第 6 行
let zipFunc = zipWith(call);
因此 zipWith()
的 callback 並不是傳入 arrow function,而是傳入 Ramda 的 call()
,它將會執行 array 中的 function,至於第二個 argument 已經被 point-free,因此不用提供。
Wink-fp
import { inc, dec, negate } from 'ramda'
import { zipFunc } from 'wink-fp'
let data1 = [inc, dec, negate]
let data2 = [1, 2, 3]
zipFunc(data1)(data2) // ?
Wink-fp 已經內建 zipFunc()
,可直接使用。
zipFunc()
[a -> b] -> [a] -> [b]
將 array 中 function 套用到另一 array
Conclusion
call()
看似不起眼,但搭配zipWith()
卻出現很神奇效果,其實這也正是 FP 精神:將很多小 function 組合成大 function- FP 強調 function as data,但 function 最終還是要執行,因此
call()
是 function 的啟動器
Reference
Ramda Cookbook, Apply a list of functions in a specific order into a list of values
Ramda, zipWith()
Ramda, call()
Ramda, inc()
Ramda, dec()
Ramda, negate()