如何用jq提取并修改包含父对象数据的内部数组对象
问题
需要将指定格式的JSON转换为目标结构,具体需求如下:
- 移除null记录
- 为无type字段的记录设置默认值"UNKN"
- 为所有记录添加
wanted_key:true - 从含
changes字段的父记录中,创建继承父记录type字段的新子记录,并将所有记录合并到一个数组中
现有JSON输入:
[{"id":1,"type":"A","changes":[{"id":12},{"id":13}],"wanted_key":"good","unwanted_key":"aaa"},{"id":2,"type":"A","unwanted_key":"aaa"},{"id":3,"type":"B","changes":[{"id":31},{"id":32}],"unwanted_key":"aaa","unwanted_key2":"aaa"},{"id":4,"type":"B","unwanted_key3":"aaa"},null,null,{"id":7}]
目标JSON输出:
[{"id":1,"type":"A","wanted_key":true},{"id":12,"type":"A","wanted_key":true},{"id":13,"type":"A","wanted_key":true},{"id":2,"type":"A","wanted_key":true},{"id":3,"type":"B","wanted_key":true},{"id":31,"type":"B","wanted_key":true},{"id":32,"type":"B","wanted_key":true},{"id":4,"type":"B","wanted_key":true},{"id":7,"type":"UNKN","wanted_key":true}]
目前已完成删除null记录、设置字段默认值的操作,现有jq代码:
del(..|nulls) | map({id, type: (.type // "UNKN"), wanted_key: (true)}) | del(..|nulls)
解决方案
可以通过flatmap实现父记录与子记录的展开合并,同时完成所有需求,完整jq代码如下:
del(..|nulls) | flatmap( [ {id, type: (.type // "UNKN"), wanted_key: true}, (.changes // [] | map({id, type: (.type // ($parent.type // "UNKN")), wanted_key: true})) ] )
代码说明:
del(..|nulls):移除所有null记录,保留有效数据。flatmap(...):遍历每个父记录,将父记录本身和其生成的子记录数组扁平化,直接合并到结果数组中,避免嵌套。- 父记录处理:
{id, type: (.type // "UNKN"), wanted_key: true},提取id字段,为无type的记录设置默认值"UNKN",强制将wanted_key设为true(覆盖原有值)。 - 子记录处理:
(.changes // []):若父记录无changes字段,用空数组替代,避免报错。map({id, type: (.type // ($parent.type // "UNKN")), wanted_key: true}):遍历changes中的子记录,继承父记录的type作为子记录的默认type值,同时设置wanted_key为true,保留子记录的id。
内容的提问来源于stack exchange,提问作者ateam
相关产品推荐
相关产品推荐

