實務上常將 Array 中 Object 的某個 Property 取出其 Value 成為新 Array,且不希望有 Object 與 Key,此時可使用 pluck()
取代 map(prop())
。
Version
Ramda 0.27.1
Imperative
let data = [
{ title: 'FP in JavaScript', price: 100 },
{ title: 'RxJS in Action', price: 200 },
{ title: 'Speaking JavaScript', price: 300 }
]
let f = (k, a) => {
let result = []
for (let x of a)
result.push(x[k])
return result
}
f('title', data) // ?
若我們只想取得 title
property 資料並回傳新 Array,pluck()
只要傳入 title
與 data
即可。
Imperative 會使用 for
loop 將 title
property 取出塞入 result
array 回傳。
ECMAScript
reduce()
let data = [
{ title: 'FP in JavaScript', price: 100 },
{ title: 'RxJS in Action', price: 200 },
{ title: 'Speaking JavaScript', price: 300 }
]
let f = (k, a) => a.reduce((ac, x) => [...ac, x[k]], [])
f('title', data) // ?
只要能使用 for
loop,就能使用 reduce()
改寫。
map()
let data = [
{ title: 'FP in JavaScript', price: 100 },
{ title: 'RxJS in Action', price: 200 },
{ title: 'Speaking JavaScript', price: 300 }
]
let f = (k, a) => a.map(x => x[k])
f('title', data) // ?
熟悉 FP 的人直覺會用 map()
實現。
Ramda
import { map } from 'ramda'
let data = [
{ title: 'FP in JavaScript', price: 100 },
{ title: 'RxJS in Action', price: 200 },
{ title: 'Speaking JavaScript', price: 300 }
]
let f = k => map(x => x[k])
f('title')(data) // ?
也可使用 Ramda 的 map()
使 f()
能 point-free。
Point-free
import { map, prop } from 'ramda'
let data = [
{ title: 'FP in JavaScript', price: 100 },
{ title: 'RxJS in Action', price: 200 },
{ title: 'Speaking JavaScript', price: 300 }
]
let f = k => map(prop(k))
f('title')(data) // ?
也可使用 Ramda 的 prop()
使 map()
的 callback 也 point-free。
Function Pipeline
import { pipe, map, prop } from 'ramda'
let data = [
{ title: 'FP in JavaScript', price: 100 },
{ title: 'RxJS in Action', price: 200 },
{ title: 'Speaking JavaScript', price: 300 }
]
pipe(
prop,
map
)('title')(data) // ?
也可使用 pipe()
將 prop()
與 map()
組合起來,這樣連 k
也 point-free 了。
pluck()
import { pluck } from 'ramda'
let data = [
{ title: 'FP in JavaScript', price: 100 },
{ title: 'RxJS in Action', price: 200 },
{ title: 'Speaking JavaScript', price: 300 }
]
pluck('title', data) // ?
由於 pluck()
經常使用,且是 FP 代表性 function,因此 Ramda 已經內建可直接使用。
pluck()
Functor f => k → f {k: v} → f v
從 Functor 的特定 property 的 value 取出,成為新 Functor
k
:object 的 key
f {k: v}
:Functor 內為 object
f v
:回傳 Functor 內為 value
Conclusion
- 當出現
map(prop(k))
或pipe(prop, map)
,別忘了使用pluck()
重構