使用jq仅折叠特定单元素数组且不依赖walk函数的方案咨询
jq 仅折叠指定单元素数组的实现方案(兼容低版本环境)
需求说明
需要将JSON结构中所有长度为1的group数组转换为内部单个对象,移除数组结构,同时保留其他字段(如data)的数组结构,且方案需要兼容无内置walk函数的jq 1.6以下版本。
输入JSON样例
[ { "id2": "A", "group": [ { "data": [ { "id1": 1, "group": [ { "data": [ { "a": 1, "b": 1 }, { "a": 2, "b": 2 } ], "type": "test" } ], "type": "B" } ], "type": "C" } ] }, { "id2": "C", "group": [ { "data": [ { "id1": 3, "group": [ { "data": [ { "a": 1, "b": 1 } ], "type": "test" } ], "type": "B" } ], "type": "C" } ] } ]
期望输出结果
[{ "id2": "A", "group": { "data": [{ "id1": 1, "group": { "data": [{ "a": 1, "b": 1 }, { "a": 2, "b": 2 } ], "type": "test" }, "type": "B" }], "type": "C" } }, { "id2": "C", "group": { "data": [{ "id1": 3, "group": { "data": [{ "a": 1, "b": 1 }], "type": "test" }, "type": "B" }], "type": "C" } } ]
此前方案问题
- 直接使用
walk(if type=="array" and length==1 then .[0] else . end)会误删data字段的单元素数组结构,不符合需求 - jq 1.6以下版本无内置
walk函数,无法直接调用内置实现
兼容低版本jq的可行方案
手动定义walk函数,仅针对group字段做单元素数组折叠处理,代码如下:
def walk(f): . as $in | if type == "object" then reduce keys_unsorted[] as $key ( {}; . + { ($key): ($in[$key] | walk(f)) } ) | f elif type == "array" then map( walk(f) ) | f else f end; walk(if type=="object" and has("group") and (.group | type)=="array" and (.group | length)==1 then .group = .group[0] else . end)
该方案逻辑为自定义递归遍历函数,仅当检测到对象包含group字段、且该字段是长度为1的数组时,才将其替换为数组内的第一个元素,其他结构保持不变,可完美适配需求同时兼容低版本jq环境。
内容的提问来源于stack exchange,提问作者basidio
相关产品推荐
相关产品推荐

