點燈坊

失くすものさえない今が強くなるチャンスよ

使用 transduce() 組合 sum()

Sam Xiao's Avatar 2020-12-05

transduce() 並不適用所有 function,必須是 transducer 方可使用,sum() 就是典型非 transducer。

Version

Ramda 0.27.1

pipe()

import { pipe, filter, where, includes, pluck, sum } from 'ramda'

let data = [
  { title: 'FP in JavaScript', price: 100 },
  { title: 'Programming Haskell', price: 200 },
  { title: 'Speaking JavaScript', price: 300 }
]

pipe(
  filter(where({ title: includes('JavaScript') })),
  pluck('price'),
  sum
)(data) // ?

pipe() 內組合了 sum() 加總了所有符合 filter() 條件的 price。

number000

transduce()

import { compose, filter, where, includes, pluck, transduce, add } from 'ramda'

let data = [
  { title: 'FP in JavaScript', price: 100 },
  { title: 'Programming Haskell', price: 200 },
  { title: 'Speaking JavaScript', price: 300 }
]

let f = compose(
  filter(where({ title: includes('JavaScript') })),
  pluck('price')
)

transduce(f, add, 0, data) // ?

若要改用 transduce(),除了將原本 function 改用 compose(),還不能使用 sum(),因為 sum() 非 transducer。

sum() 原本工作則改在 transduce() 內執行:

  • Iterator function 改用 add(),因為 add() 的兩個 argument 意義相同,因此不必如 Array 時得使用 flip(append)
  • 因為 sum() 最後結果是 Number,因此初始值為 0

number001

Conclusion

  • transduce() 的 iterator function 不見的永遠都是 flip(append),若最後結果是 Number,使用 add 即可
  • transduce() 的初始值也不一定都是 [] Empty Array,若結果是 Number 則初始值是 0

Reference

Ramda, transduce()