點燈坊

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

使用 mapObjIndexed() 改變 Object 的 Value

Sam Xiao's Avatar 2019-07-06

在 Array,我們有 map() 能在 Length 不變前提下,改變其 Element;若要在 Object 的 Key 不變前提下,根據其 Key 改變 Value,Ramda 提供了 mapObjIndexed()

Version

Ramda 0.27.1

Change Value by Key

import { pipe, mapObjIndexed } from 'ramda'

let data = {
  'FP in JavaScript': 100,
  'Programming Haskell': 200,
  'Speaking JavaScript': 300
}

pipe(
  mapObjIndexed((val, key) => `Price of ${key} is ${val}`)
)(data) // ?

data 為 Object,我們希望在 key 不變前提下,將 value 改成類似 Price of FP in JavaScript is 100 格式,其中 value 改變還牽涉到 key,此時就很適合使用 mapObjIndexed()

mapObjIndexed()
((*, String, Object) → *) → Object → Object
Object 版的 map(),提供 value 與 key 給 callback 使用

(*, String, Object) -> *:callback,其中 * 為 value,String 為 key,Object 原本的 Object。

Object:data 為 Object

Object:回傳 map 後的 Object

map000

Only Change by Value

import { pipe, mapObjIndexed } from 'ramda'

let data = {
  'FP in JavaScript': 100,
  'Programming Haskell': 200,
  'Speaking JavaScript': 300
}

pipe(
  mapObjIndexed(val => `Price is ${val}`)
)(data) // ?

若 value 改變不牽涉到 key,只與 value 有關,則 callback 可以不用傳入 key,只傳入 value 即可。

map001

import { pipe, map } from 'ramda'

let data = {
  'FP in JavaScript': 100,
  'Programming Haskell': 200,
  'Speaking JavaScript': 300
}

pipe(
  map(val => `Price is ${val}`)
)(data) // ?

事實上若 value 改變不牽涉到 key,只與 value 有關,其實使用 map() 亦可。

map002

Conclusion

  • mapObjIndexed() 算比較少用的 function,若 object 的 key 也需要參與運算,才會使用到 mapObjIndexed()
  • Callback 的第三個參數雖然是 Object,但實務上較少使用
  • 若 value 改變只牽涉到 value,不牽涉到 key,其實可用 map() 亦可

Reference

Ramda, mapObjIndexed()