map()
的 Callback 常需要常需要從 Object 取得 Property,可使用 Ramda 的 prop()
使 Callback 能 Point-free。
Imperative
let data = [
{ title: 'FP in JavaScript', price: 100 },
{ title: 'RxJS in Action', price: 200 },
{ title: 'Speaking JavaScript', price: 300 }
]
let f = k => arr => {
let result = []
for(let x of arr)
result.push(x[k])
return result
}
f('title')(data) // ?
若我們只需要 array 指定 property,imperative 會使用 for
loop 並使用 []
取得指定 property。
ECMAScript
reduce()
let data = [
{ title: 'FP in JavaScript', price: 100 },
{ title: 'RxJS in Action', price: 200 },
{ title: 'Speaking JavaScript', price: 300 }
]
let f = k => arr => arr.reduce((a, x) => [...a, 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 => arr => arr.map(x => x[k])
f('title')(data) // ?
可使用 ECMAScript 自帶的 map()
取代 for
loop,並在 arrow function 內取得指定 property。
Ramda
import { prop, 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()
取代,並使 arr
argument point-free。
prop()
import { map } from 'ramda'
let data = [
{ title: 'FP in JavaScript', price: 100 },
{ title: 'RxJS in Action', price: 200 },
{ title: 'Speaking JavaScript', price: 300 }
]
let prop = k => obj => obj[k]
let f = k => map(prop(k))
f('title')(data) // ?
若要使 map()
的 callback 也 point-free,可自行實作 prop()
取代 []
。
import { prop, map } from 'ramda'
let data = [
{ title: 'FP in JavaScript', price: 100 },
{ title: 'RxJS in Action', price: 200 },
{ title: 'Speaking JavaScript', price: 300 }
]
let f = v => map(prop(v))
f('title')(data) // ?
Ramda 已經提供 prop()
可直接使用。
prop()
s -> {s: a} -> a | undefined
傳入 key 與 object,傳回 value
s
:object 的 key
{s: a}
:data 為 object
a | undefined
:傳回 value,若找不到為 undefined
compose()
import { prop, map, 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(map, prop)
f('title')(data) // ?
也可使用 compose()
將 map()
與 prop()
組合起來。
Conclusion
prop()
會傳回 Ramda 所需要的 callback,只要傳入 object 的 property 名稱即可- FP 的 data 都會放在最後一個 argument,因此可輕鬆做 point-free
Reference
MDN, Array.prototype.reduce()
MDN, Array.prototype.map()
Ramda, map()
Ramda, prop()
Ramda, compose()