如何使用jq过滤器将以List结尾的父字段替换为其子字段?
用jq实现JSON层级简化:移除以"List"结尾的冗余字段层级
需求说明
需要将JSON中所有以List结尾的字段的值提升到父层级,同时去掉字段名末尾的List后缀,消除冗余嵌套结构。比如将"foobarList": {"foobar": 2}转换为"foobar": 2,深层嵌套的结构也需要递归处理。
核心jq过滤器
def liftList: if type == "object" then to_entries | map( if .key | test("List$") then .value | to_entries[] | {key: .key, value: .value} else .key as $k | .value | liftList | {key: $k, value: .} end ) | from_entries elif type == "array" then map(liftList) else . end; liftList
逻辑解释
这个递归函数liftList会遍历JSON的所有层级,处理不同类型的元素:
- 对象类型:
- 先把对象转为键值对数组(
to_entries) - 逐个处理每个键值对:
- 如果键名以
List结尾,直接取出该字段对应的对象值,将其内部的键值对提升到当前层级,替换原来的List字段 - 如果键名不符合规则,递归处理该字段的值,再保留原键名
- 如果键名以
- 最后把处理后的键值对数组转回对象(
from_entries)
- 先把对象转为键值对数组(
- 数组类型:递归处理数组中的每一个元素
- 基础类型(数字、字符串、布尔等):直接返回原值,不做修改
效果验证
原JSON结构:
{ "foo": [ { "foobarList": { "foobar": 2 } }, { "raboofList": { "raboof": [3, 5, 7] } } ], "bazList": { "baz": 11 }, "foobar": { "barbazList": { "barbaz": [13, 17, 19] }, "foobazList": { "foobaz": { "barfooList": { "barfoo": [23, 29] } } } } }
处理后得到目标结构:
{ "foo": [ { "foobar": 2 }, { "raboof": [3, 5, 7] } ], "baz": 11, "foobar": { "barbaz": [13, 17, 19], "foobaz": { "barfoo": [23, 29] } } }
内容的提问来源于stack exchange,提问作者rickhg12hs
相关产品推荐
相关产品推荐

