Ramda如何对嵌套对象数组排序 字符串转数字保留完整对象
Ramda 嵌套字段数值排序保留完整对象方案
问题场景
需要对嵌套结构的对象数组排序,要求按nodeLayout.x的数值升序排列,排序后返回保留所有属性的完整对象,且排序逻辑可直接整合进现有Ramda过滤管道。
待排序示例数据:
const testArray = [ { "id": "1", "nodeLayout": { "x": "12.0", "y": "1.0", "width": 200, "height": 87 } }, { "id": "2", "nodeLayout": { "x": "1.0", "y": "1.0", "width": 200, "height": 87 } }, { "id": "3", "nodeLayout": { "x": "0.0", "y": "1.0", "width": 200, "height": 87 } } ]
已尝试的无效方案
之前实现的排序逻辑仅返回提取后的x值,无法保留完整对象:
R.pipe( R.pluck('nodeLayout'), R.map(R.pipe(R.props(['x']), R.join(','))), R.sortWith([R.ascend(parseFloat)]) )(testArray)
尝试直接在过滤管道后加R.sortBy(R.path(['nodeLayout', 'x']))时,因为x字段是字符串类型,会按字符串字典序排序而非数值排序,不符合需求。
现有待补充的管道代码:
R.pipe( R.filter( R.allPass([ R.pathEq(['nodeLayout', 'y'], '1.0'), R.propEq('group', 4) ] )) // 待补充排序逻辑 )(testArray)
实现代码
直接在sortBy的取值函数中组合「取嵌套字段」+「转数值」逻辑即可,排序时会基于转换后的数值比较,最终返回原对象结构:
R.pipe( R.filter( R.allPass([ R.pathEq(['nodeLayout', 'y'], '1.0'), R.propEq('group', 4) ]) ), // 核心排序逻辑 R.sortBy(R.pipe( R.path(['nodeLayout', 'x']), parseFloat )) )(testArray)
如果需要多字段排序,使用sortWith时写法一致:
R.pipe( R.filter( R.allPass([ R.pathEq(['nodeLayout', 'y'], '1.0'), R.propEq('group', 4) ]) ), R.sortWith([ R.ascend(R.pipe(R.path(['nodeLayout', 'y']), parseFloat)), R.ascend(R.pipe(R.path(['nodeLayout', 'x']), parseFloat)) ]) )(testArray)
注意事项
- 上述示例代码运行后,示例数组的返回顺序为id:3 → id:2 → id:1,符合数值升序预期
- 如果字段存在空值/非数字值,可以追加默认值处理避免NaN异常:
R.pipe(R.path(['nodeLayout', 'x']), parseFloat, R.defaultTo(0))
内容的提问来源于stack exchange,提问作者omygoodness
相关产品推荐
相关产品推荐

