點燈坊

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

使用 where() 產生 Object 的 Predicate

Sam Xiao's Avatar 2020-12-06

由於 filter() 這類 Function 需要傳進 Predicate,若 Data 為 Object Array,勢必先取出 Property 再進行比較,勢必使用 pipe() 產生 Predicate,此時可改用 where() 可讀性更高。

Version

Ramda 0.27.1

filter()

import { pipe, filter, prop, 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(pipe(prop('title'), includes('JavaScript'))),
  pluck('price'),
  sum
)(data) // ?

若我們要取得 title 包含 JavaScript 的所有 price 總和,在 filter() 內須做兩件事情:

  • 使用 prop() 先取得 title 內容
  • 使用 includes() 判斷是否包含 JavaScript
  • 最後使用 pipe() 組合

這樣雖然可行,但可讀性較差。

where000

where()

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) // ?

Ramda 提供了 where() 特別適合 Object Array:

where()
{String: (* → Boolean)} → {String: *} → Boolean
提供 Object Array 所需 predicate

{String: (* → Boolean)}String 為 Object 的 property,(* → Boolean) 則為判斷 function

{String: *} -> Boolean:回傳 argument 為 Object 的 predicate

where001

Conclusion

  • 當 data 為 Object Array 時,建議都該使用 where() 產生 predicate,而非土法煉鋼使用 pipe() 組合

Reference

Ramda, where()