使用 map()
時若需對值做簡單轉換,直覺會在 Arrow Function 內使用 if else
對應,事實上可以使用 lookup()
以 Point-free 實現。
Version
Wink-fp 1.26.0
if else
import { map } from 'ramda'
let data = [100, 200, 300, 400]
map(x => {
if (x === 100) return 60
else if (x === 200) return 70
else if (x === 300) return 80
else return 100
})(data) // ?
若 100
則轉成 60
,200
則轉成 70
,300
則轉成 80
,其餘則轉成 100
,直覺會在 map()
內使用 if else
轉換。
Object
import { map } from 'ramda'
let data = [100, 200, 300, 400]
map(x => {
let lookupTable = {
100: 60,
200: 70,
300: 80
}
let result = lookupTable[x]
return !result ? 50 : result
})(data) // ?
40 行
let lookupTable = {
100: 60,
200: 70,
300: 80
}
let result = lookupTable[x]
return !result ? 50 : result
使用 Object 作為 lookup table 為 JavaScript 常用技巧,別忘了查詢不到時會回傳 undefined
,藉由 falsy value 判斷回傳 default value。
lookup()
import { map, propOr, curry } from 'ramda'
let data = [100, 200, 300, 400]
let lookup = curry((a, o, k) => propOr(a, k , o))
map(lookup(50, {
100: 60,
200: 70,
300: 80
}))(data) // ?
使用 lookup table 雖然能取代 if else
,但若能使 map()
能 Point-free 不使用 arrow function 就更完美了。
第 5 行
let lookup = curry((a, o, k) => propOr(a, k , o))
lookup table 本質是 Object,Ramda 的 propOr()
剛好適合,只是其 signature 不方便使用,特別建立 lookup()
調整 signature。
第 7 行
map(lookup(50, {
100: 60,
200: 70,
300: 80
}))(data) // ?
lookup()
第一個 argument 提供 default value,第二個 argument 提供 lookup table。
Wink-fp
import { map } from 'ramda'
import { lookup } from 'wink-fp'
let data = [100, 200, 300, 400]
map(lookup(50, {
100: 60,
200: 70,
300: 80
}))(data) // ?
Wink-fp 已經提供 lookup()
可直接使用。
lookup()
a -> Object -> String -> a
提供 default value 與 lookup table 取代 if else
Conclusion
lookup()
本質是 Ramda 的propOr()
,只是將其 signature 順序加以調整方便使用