Python中使用pyjq将metrics嵌套数组映射为顶层字段 解决笛卡尔积问题
结果变成36条的核心原因
你这是踩了jq的笛卡尔积求值规则的坑:在构造JSON对象的时候,每个字段对应的表达式如果会触发数组遍历,是会独立执行、最后交叉配对的。
- 你写的
valueQuantity字段,是从.metrics[]遍历拿数据,会产出6个中间结果 - 你写的
category字段,又独立写了.metrics[].type,会再独立遍历一次metrics,又产出6个中间结果 - 两组独立遍历的结果两两组合,就得到6*6=36条对象,和你要的单数组映射逻辑完全不搭。
正确写法
核心原则:数组遍历动作要前置到管道最前面,让上下文落在单个元素上,绝对不要在同一个对象构造块里重复遍历同一个源数组
正确的jq映射表达式:
.metrics[] | { "valueQuantity": { "unit": .unit, "value": .value }, "category": .type }
- 先通过管道把
.metrics[]的遍历走起来,每一次管道流转,上下文都会是单个metrics条目 - 构造对象的时候,直接从当前上下文取
unit、value、type三个字段就可以,不会触发额外遍历,最终输出的条数和原metrics数组长度完全一致,就是你要的6条结果。
对应的完整pyjq调用:
import pyjq # 原始输入数据 data = { "metrics": [ {"type":"active_duration","unit":"s","value":135.0}, {"type":"basal_energy_burned","unit":"kcal","value":2371.7412956}, {"type":"distance","unit":"m","value":1510.36558533}, {"type":"active_energy_burned","unit":"kcal","value":295.203469907}, {"type":"steps","unit":"count","value":1877}, {"type":"energy_burned","unit":"kcal","value":2666.944765507} ] } # 执行映射 mapped_result = pyjq.all( '.metrics[] | { "valueQuantity": { "unit": .unit, "value": .value }, "category": .type }', data )
执行完mapped_result的结构、条数完全匹配你给的期望输出格式。
内容的提问来源于stack exchange,提问作者Alex Fragotsis
相关产品推荐
相关产品推荐

