點燈坊

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

如何將 Array 轉成 Object ?

Sam Xiao's Avatar 2020-11-22

實務上 API 多半回傳 Object Array,但若想當做 Map 使用時 Object 會比較方便,因此常常需要將 Object Array 轉成 Object。

Version

Ramda 0.27.1

Imperative

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

let f = a => {
  let result = {}

  for (let x of a)
    result[x.title] = x.price

  return result
}

f(data) // ?

第 3 行

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

data 內的 Object 有 titleprice,但由於想當 Map 使用,因此希望結果為以下 Object。

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

第 9 行

let f = arr => {
  let result = {}

  for (let x of arr)
    result[x.title] = x.price

  return result
}

Imperative 會使用 for loop,因為結果為 Object,所以 result 初始值為 {}

for loop 中使用 ECMAScript 獨家的 [] 動態新增 property,最後回傳 result Object。

object000

reduce()

import { reduce } from 'ramda'

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

let f = reduce((ac, x) => ({...ac, [x.title]: x.price}), {})

f(data) // ?

由於 input 為 Array,回傳結果為 Object,型別完全不同,很適合 reduce()

第 9 行

let f = reduce((ac, x) => ({...ac, [x.title]: x.price}), {})

將累計的 ...ac 展開,再使用 {} 動態重新組合 object。

object001

fromPairs()

import { pipe, map, props, fromPairs } from 'ramda'

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

pipe(
  map(props(['title', 'price'])),
  fromPairs
)(data) // ?
  • 使用 map(props) 取得 value 部分
  • 使用 fromPairs() 將 Nested Array 轉成 Object

object002

plucks()

import { pipe, fromPairs } from 'ramda'
import { plucks } from 'wink-fp'

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

pipe(
  plucks(['title', 'price']),
  fromPairs
)(data) // ?

也可使用 plucks() 取代 map(props)

object003

Conclusion

  • 實務上應先考慮 higher order function,若真的無招時,就是出大絕使用 reduce() 的時機

Reference

Ramda, reduce()
Ramda, fromPairs()