zipWith()
只能將 2 個 Array 合併,若要將 n 個 Array 合併呢 ? Ramda 並沒有提供適當 Function,我們可自行組合出 zipAllWith()
。
Version
macOS Catalina 10.15.3
VS Code 1.41.1
Quokka 1.0.276
Ramda 0.26.1
Wink-fp 1.20.47
zipWith()
import { reduce, zipWith, add, head, tail } from 'ramda'
let data = [[1, 2, 3], [4, 5, 6], [7, 8, 9]]
let _result = zipWith(add)([1, 2, 3])([4, 5, 6]) //?
let result = zipWith(add)(_result)([7, 8, 9]) // ?
若使用 zipWith()
,我們只能先傳入 [1, 2, 3]
與 [4, 5, 6]
先合併,然後將結果 _result
在與 [7, 8, 9]
合併。
reduce()
import { reduce, zipWith, add, head, tail } from 'ramda'
let data = [[1, 2, 3], [4, 5, 6], [7, 8, 9]]
reduce(zipWith(add))(head(data))(tail(data)) // ?
由於 data
是 array,因此可透過 reduce()
循環執行,初始值以 head(data)
取得 [1, 2, 3]
,data 以 tail(data)
取得剩下的 [[4, 5, 6], [7, 8, 9]]
。
zipAllWith()
import { reduce, zipWith, head, tail, add, converge } from 'ramda'
let data1 = [1, 2, 3]
let data2 = [4, 5, 6]
let data3 = [7, 8, 9]
let zipAllWith = f => converge(
reduce(zipWith(f)), [head, tail]
)
zipAllWith(add)([data1, data2, data3]) // ?
是否能更一般化組合出 zipAllWith()
呢 ?
我們可發現 data 經過 head()
與 tail()
處理後,最後再交給 reduce(zipWith())
處理,這剛好是 converge()
的形式。
由於 zipWith()
重點在於傳入的 callback,zipAllWith()
也依然保有傳入 callback 的特性。
Wink-fp
import { add } from 'ramda'
import { zipAllWith } from 'wink-fp'
let data1 = [1, 2, 3]
let data2 = [4, 5, 6]
let data3 = [7, 8, 9]
zipAllWith(add)([data1, data2, data3]) // ?
Wink-fp 已經內建 zipAllWith()
可直接使用。
zipAllWith()
((a, a) -> b) -> [[a]...] -> [b]
自行提供 function 將 n 個 array 合併
Conclusion
- Ramda 所提供的 function 其 data 都是一個與兩個,若要 n 個,可使用本文方式透過 array 與
reduce()
加以擴充