點燈坊

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

使用 lensPath() 對複雜資料結構建立 Lens

Sam Xiao's Avatar 2021-04-23

lensPath() 可針對複雜資料結構建立 Lens,如 Nested Object、Nested Array 或 Object Array。

Version

Ramda 0.27.1

Nested Object

import { lensPath, view, set, over, inc } from 'ramda'

let data = {
  title: 'FP in JavaScript',
  price: {
    Amazon: 100,
    eBay: 200
  }
}

view(lensPath(['price', 'eBay']), data) // ?
set(lensPath(['price', 'eBay']), 400, data) // ?
over(lensPath(['price', 'eBay']), inc, data) // ?

data 為 Nested Object,可使用 lensPath() 對指定 property 建立 Lens,然後套用在 view()set()over() 上。

lensPath()
[String] → Lens s a
針對 Nested Object 建立 Lens

[String]:指定 property 以 Array 形式傳入

Lens s a:回傳 Lens

lenspath000

Nested Array

import { lensPath, view, set, over, inc } from 'ramda'

let data = [0, [1, 2]]

view(lensPath([1, 1]), data) // ?
set(lensPath([1, 1]), 10, data) // ?
over(lensPath([1, 1]), inc, data) // ?

data 為 Nested Array,可使用 lensPath() 對指定 index 建立 Lens,然後套用在 view()set()over() 上。

lensPath()
[Int] → Lens s a
針對 Nested Array 建立 Lens

[String]:指定 index 以 Array 形式傳入

Lens s a:回傳 Lens

lenspath001

Object Array

import { lensPath, view, set, over, toUpper } from 'ramda'

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

view(lensPath([0, 'title']), data) // ?
set(lensPath([0, 'title']), 'OOP in JavaScript', data) // ?
over(lensPath([0, 'title']), toUpper, data) // ?

data 為 Object Array,可使用 lensPath() 同時對指定 property 與 index 建立 Lens,然後套用在 view()set()over() 上。

lensPath()
[Int | String] → Lens s a
針對 Object Array 建立 Lens

[Int | String]:指定 index 或 property 以 Array 形式傳入

Lens s a:回傳 Lens

lenspath002

Conclusion

  • lensPath() 為強悍的 function,可針對所有複雜資料結構建立 Lens,並配合 view()set()over() 使用

Reference

Ramda, lensPath()