如何在JSONata中将分组结果与另一列表进行关联分组?
JSONata实现分组后关联多列表转换
问题描述
我正在寻找灵活定义JSON转换的方法,于是开始试用JSONata。我的场景很简单:先按字符串值对列表元素分组(这一步已经搞定),再把分组结果和另一个列表做关联分组。想知道这能不能实现?如果可以的话该怎么操作?我觉得高阶函数可能有用,但还没搞明白怎么从内部作用域访问外部作用域的对象。
示例数据
{"grades": [ { "student_name": "John Smith", "grade": "B" }, { "student_name": "Jane Doe", "grade": "A" } ], "grades_by_subject": [ { "student_name": "John Smith", "subject": "English", "grade": "A" }, { "student_name": "Jane Doe", "subject": "Math", "grade": "A+" }, { "student_name": "John Smith", "subject": "Math", "grade": "A" }, { "student_name": "Jane Doe", "subject": "English", "grade": "C-" } ] }
当前已完成的JSONata转换
{"students": grades_by_subject{`student_name`: { "grades_by_subject": $.{ "subject": subject, "grade": grade } } }}
当前转换结果
{"students": { "John Smith": { "grades_by_subject": [ { "subject": "English", "grade": "A" }, { "subject": "Math", "grade": "A" } ] }, "Jane Doe": { "grades_by_subject": [ { "subject": "Math", "grade": "A+" }, { "subject": "English", "grade": "C-" } ] } } }
期望结果
{"students": { "John Smith": { "overall_grade": { "student_name": "John Smith", "grade": "B" }, "grades_by_subject": [ { "subject": "English", "grade": "A" }, { "subject": "Math", "grade": "A" } ] }, "Jane Doe": { "overall_grade": { "student_name": "Jane Doe", "grade": "A" }, "grades_by_subject": [ { "subject": "Math", "grade": "A+" }, { "subject": "English", "grade": "C-" } ] } } }
解决方案
当然可以实现,核心是在分组的内部作用域中,通过外部变量或作用域引用关联grades数组的对应数据,以下是两种实用方法:
方法一:直接过滤匹配学生姓名
修改原有表达式,在分组对象中添加overall_grade字段,通过grades[student_name = $current.student_name]匹配对应学生的总评成绩:
{"students": grades_by_subject{`student_name`: { "overall_grade": grades[student_name = $current.student_name], "grades_by_subject": $.{ "subject": subject, "grade": grade } }}}
方法二:预分组总评成绩提升效率
先将grades数组按student_name预分组为键值对对象,后续直接通过键名引用,数据量大时更高效:
( $overallGrades := grades{`student_name`: $}; {"students": grades_by_subject{`student_name`: { "overall_grade": $overallGrades[$current.student_name], "grades_by_subject": $.{ "subject": subject, "grade": grade } }}} )
关键知识点
$current:在分组内部作用域中,代表当前处理的分组键对应的原数据项,通过它可获取当前学生姓名,实现跨列表关联。- 预分组变量:通过
$overallGrades := grades{student_name: $}将总评成绩转为键值对象,后续直接取值避免重复遍历过滤,提升转换性能。
内容的提问来源于stack exchange,提问作者Dr. Thomas C. King
相关产品推荐
相关产品推荐

