點燈坊

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

使用 applySpec() 建立新 Object

Sam Xiao's Avatar 2021-03-16

pick() 只能擷取 Object 的部分 Property,且名稱不能改變,若連名稱也要改變,就要改用 applySpec()

Version

Ramda 0.27.1

Array.prototype.map()

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

let f = a => a.map(x => ({ name: x.title, dollar: x.price }))

f(data) // ?

data 內的 Object 為 titleprice,但我們改成 namedollar

ECMAScript 內建 Array.prototype.map(),可使用 arrow function 傳入 map() ,在 arrow function 可直接將 titleprice 改成 namedollar

spec000

Ramda

import { map, applySpec, prop } from 'ramda'

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

map(applySpec({
  name: prop('title'),
  dollar: prop('price'),
}))(data) // ?

可改用 Ramda 的 map() 達成 point-free,並使用 applySpec() 進一步將 arrow function 也 point-free。

applySpec()
{k: ((a, b, …, m) → v)} → ((a, b, …, m) → {k: v})
依照 spec object 建立新 object

{k: ((a, b, …, m) → v)}:新的 spec object,其 value 為 function

(a, b, …, m):argument 會套用到所有 value function

{k: v}:回傳新的 object

applecSpec() 配合 prop(),由於 point-free,可讀性非常高,很明確看到新 property 與原 property

spec001

Conclusion

  • applySpec() 的 signature 看起來很嚇人,但只要靜下心看,其實也還好,且實際使用時,程式碼可讀性非常高

Reference

Ramda, applySpec()