如何用Ramda组合透镜提取嵌套对象中的coor数据?
构造符合需求的Ramda透镜/组合函数
要实现你想要的效果,我们需要结合Ramda的透镜和数组映射操作——因为你的数据结构里包含嵌套数组,纯透镜组合无法直接处理数组的每个元素,所以我们可以把整个逻辑封装成一个可复用的函数(或者自定义透镜),让你可以直接用R.map来处理整个data数组。
方案1:封装成组合函数(最简洁)
你可以直接用R.compose把“取数组第一个元素”和“映射每个元素获取geo.coor”这两个操作组合起来,得到一个可以直接映射的函数:
const getCoors = R.compose( // 对取到的数组,每个元素应用geo.coor的透镜 R.map(R.view(R.lensPath(['geo', 'coor']))), // 先取每个data项的第一个元素(忽略后面的空对象) R.view(R.lensIndex(0)) // 等价于R.head ); // 直接使用: const result = R.map(getCoors, data); // 输出:[[[1, 2], [4, 5]], [[8, 2], [9, 5]]]
方案2:自定义透镜(满足你想要的透镜形式)
如果你确实需要一个透镜(比如后续可能需要修改coor值),可以用R.lens创建自定义透镜,定义getter和setter逻辑:
const coorLens = R.lens( // Getter:获取目标coor数组 R.compose(R.map(R.view(R.lensPath(['geo', 'coor']))), R.view(R.lensIndex(0))), // Setter:如果需要更新coor值,可以用这个逻辑(可选,如果你只需要读取可以省略,但Ramda要求透镜必须有setter) (item, newCoors) => { // 将新的coor数组和原数组里的对象一一对应更新 const updatedGeoItems = R.zipWith( (obj, coor) => R.set(R.lensPath(['geo', 'coor']), coor, obj), R.view(R.lensIndex(0), item), newCoors ); // 把更新后的数组放回原item的第一个位置 return R.set(R.lensIndex(0), updatedGeoItems, item); } ); // 使用时需要用R.view来获取透镜聚焦的值: const result = R.map(R.view(coorLens), data); // 同样得到期望的结果
为什么纯透镜组合不行?
Ramda的lensIndex和lensPath都是针对单个值的透镜,而你的数据结构中,取完第一个元素后是一个数组,需要对数组的每个元素应用透镜——这一步是数组映射操作,不是单纯的透镜聚焦,所以无法仅用R.compose把多个基础透镜组合起来实现。我们必须把映射操作和透镜结合起来,才能处理数组的每个元素。
内容的提问来源于stack exchange,提问作者donnut
相关产品推荐
相关产品推荐

