點燈坊

失くすものさえない今が強くなるチャンスよ

使用 mapValues() 對 Object 的 Value 做 map()

Sam Xiao's Avatar 2020-08-25

map() 對於 Array 重要性毋庸置疑,是我們每天必用 Function,Object 是否也能有map(),讓我們直接提供 Function 對 Object 的 Value 修改,並回傳新 Object ?

Version

macOS Catalina 10.15.6
Ramda 0.27.1
Wink-fp 1.20.88

Functional

import { pipe, toPairs, adjust, fromPairs, multiply, map } from 'ramda'

let data = {
  'FP in JavaScript': 100,
  'RxJS in Action': 200,
  'Speaking JavaScript': 300
}

let mapValues = f => pipe(
  toPairs,
  map(adjust(1, f)),
  fromPairs
)

mapValues(multiply(0.8))(data) // ?

第 3 行

let data = {
  'FP in JavaScript': 100,
  'RxJS in Action': 200,
  'Speaking JavaScript': 300
}

data 為 Object,key 為 book title,value 為 price,我們希望對 price 都打八折。

16 行

mapValues(multiply(0.8))(data) // ?

mapValues() 用法如同 map() 一樣,第一個 argument 為 function,就可對全部 value 改變。

第 9 行

let mapValues = f => pipe(
  toPairs,
  map(adjust(1, f)),
  fromPairs
)
  • 使用 toPairs() 將 Object 轉成 Pair Array
  • 使用 map(adjust(1)) 只更改 Pair 的 [1],相當於只改 Object 的 value
  • 使用 fromPairs() 將 Pair Array 轉回 Object

map000

Wink-fp

import { multiply } from 'ramda'
import { mapValues } from 'wink-fp'

let data = {
  'FP in JavaScript': 100,
  'RxJS in Action': 200,
  'Speaking JavaScript': 300
}

mapValues(multiply(0.8))(data) // ?

mapValues() 因為經常使用,Wink-fp 已經收錄。

mapValues()
(a -> b) -> {k: a} -> {k: b}
Object 的 map(),提供 function 改變 Object 的 value

map001

Conclusion

  • adjust() 原本適合 Pair Array,但因為 Ramda 提供了 toPairs()fromPairs() 之後開啟另一個法門,使得 adjust() 也能用於 Object,因此能搭配 map() 做出神奇結果

Reference

Ramda, adjust()
Ramda, fromPairs()
Ramda, toParis()
Kyle Tilman, Ramda – R.adjust()