我能想到的输入文档的最简单版本是
{
"references": [
{
"version": 5,
"id": "id1",
"objType": "A"
},
{
"version": 4,
"id": "id2",
"objType": "B",
"referencing": []
},
{
"version": 4,
"id": "id3",
"objType": "B",
"referencing": [
{
"version": 2,
"id": "id4",
"objType": "A"
},
{
"version": 3,
"id": "id5",
"objType": "B",
"referencing": []
}
]
}
]
}
类型A的对象没有引用对象。
任何一种类型的对象都可以引用B类型的对象。
这个json需要两个输出:
输出#1是以id
值为关键字、值为version
的类型A对象的版本信息。CCD_ 3对象可以在CCD_。
{
"references": {
"id1": {"version": 5},
"id4": {"version": 2}
}
}
第二个输出类似:B类型对象的版本信息。可以是引用其他类型B
对象的B
类型对象链。
{
"references": {
"id2": {"version": 4},
"id3": {"version": 4},
"id5": {"version": 3}
}
}
使用递归decsent运算符和from_entries。你不需要遵循";参考文献";(至少不会在你的问题中产生预期的输出(
{
dependencies: [.. | select(.objType=="A")? | { key: .id, value: {version} }] | from_entries
},
{
dependencies: [.. | select(.objType=="B")? | { key: .id, value: {version} }] | from_entries
}
输出:
{
"dependencies": {
"id1": {
"version": 5
},
"id4": {
"version": 2
}
}
}
{
"dependencies": {
"id2": {
"version": 4
},
"id3": {
"version": 4
},
"id5": {
"version": 3
}
}
}
也可以合并(添加(对象,而不是从它们的条目中构建它们,这使得代码至少更短:
{
dependencies: [.. | select(.objType=="A")? | { (.id): {version} }] | add
}
您可以使用recurse
遍历文档,INDEX
创建一个以ID为键的对象,map_values
根据您的标准使用select
格式化它们的值。
jq --arg type A '
.references |= (
INDEX(.[] | recurse(.referencing[]?); .id)
| map_values(select(.objType == $type) | {version})
)
'
{
"references": {
"id1": {
"version": 5
},
"id4": {
"version": 2
}
}
}
演示
这对两个问题都有效,将A
或B
提供给--arg type
。
请注意,这是在向下递归时使用错误抑制运算符?
。如果要将遍历显式限制为.objType == "B"
,只需在select
表达式中加上前缀即可,即用recurse(select(.objType == "B") | .referencing[])
替换recurse(.referencing[]?)
。演示