Ramda 有大量 Function 需要 Predicate,若 Data 是 Object Array,則 Predicate 的 Argument 為 Object,若必須針對 Property 比較是否相等,可使用 Ramda 的 propEq()
使 Predicate 也能 Point-free。
Version
macOS Catalina 10.15.3
VS Code 1.43.0
Quokka 1.0.284
Ramda 0.27.0
Predicate
import { filter } from 'ramda'
let data = [
{ title: 'FP in JavaScript', price: 100 },
{ title: 'RxJS in Action', price: 200 },
{ title: 'Speaking JavaScript', price: 300 },
]
let f = v => filter(x => x.price === v)
f(100)(data); // ?
第 9 行
let f = v => filter(x => x.price === v)
使用 filter()
找到指定 price === 100
的 object,第一個 argument 為 predicate,因此可傳入 arrow function。
Point-free
import { filter, compose, equals, prop } from 'ramda'
let data = [
{ title: 'FP in JavaScript', price: 100 },
{ title: 'RxJS in Action', price: 200 },
{ title: 'Speaking JavaScript', price: 300 },
]
let f = v => filter(compose(equals(v), prop('price')))
f(100)(data) // ?
若想將 filter()
的 predicate 也 point-free,可使用 compose()
組合 Ramda 的 prop()
與 equals()
。
Ramda
import { filter, propEq } from 'ramda'
let data = [
{ title: 'FP in JavaScript', price: 100 },
{ title: 'RxJS in Action', price: 200 },
{ title: 'Speaking JavaScript', price: 300 },
]
let f = v => filter(propEq('price')(v))
f(100)(data) // ?
由於 compose(equals(v), prop('title'))
這類 function 實在太常使用,因此 Ramda 提供了 propEq()
。
propEq()
String -> a -> Object -> Boolean
比對 object 的 property 與 value 是否相等
String
:object 的 property
a
:要比較的 data
Object
:data 為 object
Boolean
:若相等傳回 true
,不相等傳回 false
由於
propEq()
的 currying 特性,只提供前兩個 argument,剛好回傳Object -> Boolean
,特別適合產生 predicate
Function Composition
import { filter, propEq, compose } from 'ramda'
let data = [
{ title: 'FP in JavaScript', price: 100 },
{ title: 'RxJS in Action', price: 200 },
{ title: 'Speaking JavaScript', price: 300 },
]
let f = compose(filter, propEq('price'))
f(100)(data) // ?
也可進一步使用 compose()
將 propEq()
與 filter()
組合,使 fn()
也 point-free。
Conclusion
propEq()
是實務上經常使用的 function,專門使 predicate 也 point-free