如何用JSONata实现带映射、求和与去零的数组转数组操作?
JSONata数组转换需求实现方案
需求说明
- 数组对象的
name字段若存在于映射配置中则替换为映射值,否则保留原name - 映射后同名的对象,对其数值进行求和
- 移除数值为0的对象
示例数据
源JSON
{ "additive": [ { "name": "field-1", "volume": "10" }, { "name": "field-2", "volume": "10" }, { "name": "field-3", "volume": "0" }, { "name": "field-4", "volume": "5" } ] }
映射配置
{ "field-1": "field-1-mapped", "field-2": "field-1-mapped", "field-3": "field-3-mapped" }
期望结果
{ "chemicals": [ { "name": "field-1-mapped", "value": 20 }, { "name": "field-4", "value": 5 } ] }
问题分析
原尝试代码中,$lookup无法在name无映射时返回默认值,且未实现同名数值求和的核心逻辑。
解决方案
通过分组聚合的方式可以完整实现需求,步骤如下:
- 先处理每个对象的
name映射,解决默认值问题 - 按映射后的
name分组,对每组数值求和 - 过滤掉数值为0的分组,转换为目标数组格式
完整JSONata代码
{ "chemicals": ( additive // 处理name映射、转换volume为数值,提前过滤0值 .{ "mappedName": $lookup($$.map, name) ?? name, "value": $number(volume) }[value > 0] // 按映射后的名称分组 $groupBy($, "mappedName") // 将分组结果转换为目标对象结构 .{ "name": $$.key, "value": $sum($.value) } ) }
代码细节说明
$lookup($$.map, name) ?? name:利用JSONata 1.8+支持的??空值合并运算符,当映射中无对应name时直接返回原名称[value > 0]:提前过滤数值为0的项,减少后续分组计算量$groupBy($, "mappedName"):按映射后的名称对对象分组$sum($.value):对每组内的数值求和- 最终将分组对象转换为数组,生成符合要求的结构
兼容旧版JSONata(无??运算符)
如果使用的JSONata版本不支持??,可以用$if替代:
"mappedName": $if($lookup($$.map, name), $lookup($$.map, name), name)
注意事项
- 确保映射配置作为上下文变量(
$$.map)传入,或直接将映射对象写在代码中替换$$.map - 若
volume可能为空或非数字格式,可添加兜底逻辑:$number(volume) || 0
内容的提问来源于stack exchange,提问作者Tor90
相关产品推荐
相关产品推荐

