我有一个对象,我可以过滤到我希望保留的几个路径。路径的形式如下:
[
"key1",
"key2",
"mykey"
]
[
"key3",
"key4",
"mykey"
]
我想要的是:
{ "key1":{
"key2": .key2
},
"key3":{
"key4": .key4
}
}
我能得到的最接近的是:
{ "key1":{
"key2": .key2
}
}
{ "key3":{
"key4": .key4
}
使用:
(paths(objects)|select(last(.[])=="mykey")) as $path|
getpath([$path[0],$path[1]]) as $getpath|
{($path[0]):{($path[1]):$getpath}}
虽然我可以将此输出传输到jq -s'。'命令,我找不到在原始滤波器集合中将路径的重建相加的方法。似乎过滤器在每个对象的末尾重置。 $ path似乎一次只能保存一个路径数组,而不是路径数组。这可以防止我在reduce函数中迭代$ path。
我创建了以下可运行的脚本,但我也有兴趣找到如何使用paths()函数。我还没弄明白如何让它对我非常有用。
(to_entries |
map(select(.["value"][]?|has("mykey")?))|[.[].key]) as $rooms|
(to_entries |
map(select(.["value"][]?|has("mykey")?))|[.[].value]) as $roomvals| #allows room paths to be avail
##### creates object containing only those locations and sensors within the locations that include "mykey" objs
reduce
range(0;$rooms|length) as $i ({};
.+{($rooms[$i]): ($roomvals[$i] | to_entries |
map(select(.["value"]|has("mykey")))|{(.[]["key"]):.[]["value"]})})
对这些方法的任何帮助或替代方法的建议表示赞赏。
答案 0 :(得分:0)
您所指示的输出不是JSON,而且我不清楚所需的输出是什么,但以下内容似乎已接近:
reduce inputs as $d (null; setpath( $d[0: ($d|length) - 1]; $d[-1] ) )
使用您的输入并使用jq -n,这会产生:
{
"key1": {
"key2": "mykey"
},
"key3": {
"key4": "mykey"
}
}
希望你能从这里拿走它。
def data:
{ "key1": { "key2": {"mykey": {"a": 123} } },
"key3": { "key4": {"mykey": {"b": 234} } },
"key4": { "key1": {"key2" : {"a": 123} } }
};
def selection(mykey):
. as $in
| reduce (paths(objects) | select(.[-1] == mykey)) as $path
(null; setpath($path; $in|getpath($path)) );
data | selection("mykey")
调用:jq -n -c -f example.jq
输出:
{"key1":{"key2":{"mykey":{"a":123}}},
"key3":{"key4":{"mykey":{"b":234}}}}
答案 1 :(得分:0)
在峰值回应的指导下,我现在可以更好地构建并回答我的问题了。
我扩展了他的示例中使用的峰值数据对象,因此它更好地代表了我试图解决的问题。现在数据更好地说明“key2”和“key10”具有“mykey”,而“key6”,“key8”和“key11”则没有。我想在我的问题中表达的是,我想保留“key2”和“key10”的完整路径,其中包括“另一个”以及“mykey”。我意识到对峰值示例选择标准的一个小修改就可以做到。我只需要在选择中添加一个过滤器,以保留包含“mykey”的每个路径的前两个元素:
def data:
{ "key1": { "key2": {"mykey": {"a": 123},
"another":{"q": "six"} },
"key6": {"key7": {"d": 997} } },
"key3": { "key8": {"key9": {"b": 234} },
"key10": {"mykey": {"d": 997},
"another":{"q": "seven"} } },
"key4": { "key11": {"key5" : {"a": 123} } }
};
def selection(mykey):
. as $in
| reduce (paths(objects) | select(last(.[])==mykey)|.[0:2]) as $path
(null; setpath($path; $in|getpath($path)) );
data | selection("mykey")
返回我想要的内容:
{"key1":{"key2":{"mykey":{"a":123},
"another":{"q":"six"}}},
"key3":{"key6":{"mykey":{"d":997},
"another":{"q":"seven"}}}
}
您会注意到选择现在包括“|。[0:2]”。
感谢您设置我的正确轨道的高峰。我已经投了他的答案,因为它帮助我更好地表达我的问题并给我解决它的见解。