實務上在使用 map()
時,經常是只改變某些 Property,此時當然可以在 Callback 自行組合 Object,但也可使用 Ramda 的 evolve()
使 Callback 也 Point-free。
Version
Ramda 0.27.1
map()
import { pipe, map } from 'ramda'
let data = [
{ id: 1, title: 'FP in JavaScript', price: 100 },
{ id: 2, title: 'RxJS in Action', price: 200 },
{ id: 3, title: 'Speaking JavaScript', price: 300 }
]
pipe(
map(x => ({
...x,
title: x.title.toUpperCase(),
price: x.price * 0.8
}))
)(data) // ?
對於原本的 data
,我們想做以下加工:
title
全轉成大寫price
全部打八折- 其餘 property 全部保留
標準做法是使用 map()
搭配 callback,不變的 property 使用 ...
展開。
evolve()
import { pipe, evolve, map, toUpper, multiply } from 'ramda'
let data = [
{ id: 1, title: 'FP in JavaScript ', price: 100 },
{ id: 2, title: 'RxJS in Action', price: 200 },
{ id: 3, title: 'Speaking JavaScript ', price: 300 }
]
pipe(
map(evolve({
'title': toUpper,
'price': multiply(0.8)
}))
)(data) // ?
可使用 evolve()
使 map()
的 callback 能 Point-free。
evolve()
{k: (v → v)} → {k: v} → {k: v}
Object 在 key 不變的前提下,將 value 透過 function 加以改變
{k: (v → v)}
:spec object,描述 object 該如何轉換,只要加上要改變的 key,與其對應要處理的 function 即可
{k: v}
:要改變的 source object
{k: v}
:改變結果的 target object
Conclusion
- 使用
evolve()
可使map()
的 callback 語意更清楚,而且 spec object 只要描述要改變的 property 即可