使用 ramda 组合镜头
composing lenses using ramda
我正在尝试查询嵌套对象的内容 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)
有人知道如何构造这样的镜头吗?
谢谢!
有一个 mapped
setter 的概念可用于更新透镜结构中仿函数的值,尽管这只能与 over
/[= 一起使用16=] 而不是 view
(即如何从只能由 map
修改的内容中获取元素?)
还有一种可穿越光学系统的概念,它可以关注许多元素,而不仅仅是一个元素。这使您既可以更新焦点下的所有元素,也可以说明您希望如何将许多元素组合到一个结果中,您还可以查看它们。但是,这不会为您提供完全相同的结构,因为所有聚焦元素将组合在一起,这与示例中的列表列表不同。
Ramda 本身不提供此功能,但可以在 ramda-lens 库中找到它。
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>
我觉得值得指出的是,除非您通过组合镜头的能力在这里获得任何东西,或者同时查看和更新聚焦元素,否则避免使用可以说是更直接的功能组合的镜头可能会更简单,如下所示。
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)
)
<script src="//cdnjs.cloudflare.com/ajax/libs/ramda/0.25.0/ramda.min.js"></script>
我正在尝试查询嵌套对象的内容 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)
有人知道如何构造这样的镜头吗?
谢谢!
有一个 mapped
setter 的概念可用于更新透镜结构中仿函数的值,尽管这只能与 over
/[= 一起使用16=] 而不是 view
(即如何从只能由 map
修改的内容中获取元素?)
还有一种可穿越光学系统的概念,它可以关注许多元素,而不仅仅是一个元素。这使您既可以更新焦点下的所有元素,也可以说明您希望如何将许多元素组合到一个结果中,您还可以查看它们。但是,这不会为您提供完全相同的结构,因为所有聚焦元素将组合在一起,这与示例中的列表列表不同。
Ramda 本身不提供此功能,但可以在 ramda-lens 库中找到它。
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>
我觉得值得指出的是,除非您通过组合镜头的能力在这里获得任何东西,或者同时查看和更新聚焦元素,否则避免使用可以说是更直接的功能组合的镜头可能会更简单,如下所示。
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)
)
<script src="//cdnjs.cloudflare.com/ajax/libs/ramda/0.25.0/ramda.min.js"></script>