使用ramda制作镜头

时间:2018-05-30 12:50:53

标签: ramda.js lenses

我正在尝试查询嵌套对象coor的内容。

const data = [ 
   [ [{geo: {coor: [1,2]}}, {geo: {coor: [4,5]}}], {} ], 
   [ [{geo: {coor: [8,2]}}, {geo: {coor: [9,5]}}], {} ]
 ]

结果应为:

[[[1, 2], [4, 5]], [[8, 2], [9, 5]]]

我使用以下代码来获得此结果:

const viewLens = R.view(R.lensPath(['geo', 'coor']))
R.map(R.map(viewLens), R.map(R.view(lensIndex(0)), data))

但是我想制作一个可以用来映射data的镜头,其中包括以下内容:

const coorLens = R.compose(R.lensIndex(0), ..., R.lensPath(['geo', 'coor']))

可以像:

一样使用
R.map(coorLens, data)

有人知道如何构建这样的镜头吗?

谢谢!

1 个答案:

答案 0 :(得分:1)

有一个mapped setter概念可用于更新镜头构造中的仿函数值,但这只能与over / set一起使用而不能{ {1}}(即如何从只能由view修改的内容中获取元素?)

还有一种可穿越光学器件的概念可以集中在许多元件而不仅仅是一个元件上。这使您既可以更新焦点下的所有元素,又可以说明如何将多个元素组合到一个结果中,您也可以查看它们。这不会给你完全相同的结构,因为所有关注的元素将组合在一起,而不像你的例子中的列表列表。

Ramda本身不提供此功能,但可以在ramda-lens库中找到。



map

const RL = ramdaLens

const data = [ 
  [ [{geo: {coor: [1,2]}}, {geo: {coor: [4,5]}}], {} ], 
  [ [{geo: {coor: [8,2]}}, {geo: {coor: [9,5]}}], {} ]
]

const coorLens = R.compose(
  RL.traversed,
  R.lensIndex(0),
  RL.traversed,
  R.lensPath(['geo', 'coor'])
)

console.log(
  "Combine all the focused elements in a list\n",
  RL.listOf(coorLens, data)
)

console.log(
  "Update all the focused elements\n",
  RL.over(coorLens, R.map(R.inc), data)
)




我觉得值得指出的是,除非你通过组合镜头的能力获得任何东西,或者既可以查看和更新​​聚焦元素,也可以更简单地避免使用可以说更直接的功能组合的镜头下方。



<script src="//cdnjs.cloudflare.com/ajax/libs/ramda/0.25.0/ramda.min.js"></script>
<script src="https://wzrd.in/standalone/ramda-lens"></script>
&#13;
const data = [ 
  [ [{geo: {coor: [1,2]}}, {geo: {coor: [4,5]}}], {} ], 
  [ [{geo: {coor: [8,2]}}, {geo: {coor: [9,5]}}], {} ]
]

const fn = R.map(R.pipe(R.head, R.map(R.path(['geo', 'coor']))))

console.log(
  "Without lenses\n",
  fn(data)
)
&#13;
&#13;
&#13;