點燈坊

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

如何將 CSV 轉成 Object Array ?

Sam Xiao's Avatar 2021-01-31

若資料是 CSV,可透過 Ramda 輕易將其轉成 Object Array。

Version

Ramda 0.27.1

CSV to Array

import { pipe, map, split, head, tail, zipObj, evolve } from 'ramda'

let data = 
`title,price
FP in JavaScript,100
Programming Haskell,200
Speaking JavaScript,300`

let header = pipe(
  split('\n'),
  head,
  split(',')
)

let strToObj = pipe(
  split(','),
  zipObj(header(data)),
  evolve({ price: Number }),
)

pipe(
  split('\n'),
  tail,
  map(strToObj)
)(data) // ?

第 3 行

let data = 
`title,price
FP in JavaScript,100
Programming Haskell,200
Speaking JavaScript,300`

資料為 CSV,我們希望轉成 Object Array。

第 9 行

let header = pipe(
  split('\n'),
  head,
  split(',')
)

首先處理 CSV 的 header 部分:

  • split('\n'):CSV 可以視為 String,每列以 \n 隔開,將其轉成 Array
  • head():CSV 的第一列為欄位,取得後回傳 String
  • split(','):將 String 轉成 Array

21 行

pipe(
  split('\n'),
  tail,
  map(strToObj)
)(data) // ?

處理 CSV 的 body 部分:

  • split('\n'):將 CSV 轉成 Array
  • tail():取得除了第一筆以外的剩餘筆數
  • map(strToObj):將剩餘筆數轉成 Object Array

15 行

let strToObj = pipe(
  split(','),
  zipObj(header(data)),
  evolve({ price: Number }),
)

將 String 轉成 Object Array,這也是最關鍵部分:

  • split(','):將 String 轉成 Array
  • zipObj(header(data))header(data) 回傳 header 部分 Array,使用 zipObject() 將 header 與 body 合併成 Object
  • evolve({ price: Number }):將 Number 部分去掉雙引號

csv000

Conclusion

  • CSV 轉成 Object 本質上就是一連串的轉換過程,特別適合使用 Ramda 實現