使用jq在JSON对象中查找公共键
我试图在Json文件中查找所有公共密钥,因为我们不知道文件中的密钥名称 Json文件如下所示:使用jq在JSON对象中查找公共键,json,key,jq,set-intersection,Json,Key,Jq,Set Intersection,我试图在Json文件中查找所有公共密钥,因为我们不知道文件中的密钥名称 Json文件如下所示: { "DynamicKey1" : { "foo" : 1, "bar" : 2 }, "DynamicKey2" : { "bar" : 3 }, "DynamicKey3" : { "foo" : 5, "zyx" : 5 } } 预期结果: { "foo" } 我试图在这里应用reduce/for
{
"DynamicKey1" : {
"foo" : 1,
"bar" : 2
},
"DynamicKey2" : {
"bar" : 3
},
"DynamicKey3" : {
"foo" : 5,
"zyx" : 5
}
}
预期结果:
{
"foo"
}
我试图在这里应用reduce/foreach逻辑,但我不知道如何在jq中编写它。谢谢你的帮助
jq '. as $ss | reduce range(1; $ss|length) as $i ([]; . + reduce ($ss[i] | keys) as $key ([]; if $ss[$i - 1] | has($key) then . +$key else . end))' file.json
发布的Q中存在一些不一致之处:没有所有对象的公共键,如果查看键的成对相交,结果将包括“foo”和“bar” 在下面,我将介绍这两个问题的解决方案 在多个对象中设置关键帧 所有对象中的关键点 以下是使用类似方法的解决方案:
length as $length
| [.[] | keys_unsorted[]] | group_by(.)[]
| select(length==$length)
| .[0]
这涉及到使用排序来实现的groupby/2
这里是一种依赖内置函数键
进行排序的替代方法(要点是((nk ln(nk))-n(k ln(k)))=nk ln(n),即具有n个小种类的k项比一个大种类的n*k项好):
下面是一个无排序且高效的答案,它依赖于jq在JSON字典中实现查找的效率。由于键是字符串,我们可以简单地使用“单词包”(
bow
)的概念:
我们现在可以解决“所有对象共有的关键点”问题,如下所示:
length as $length
| bow(.[] | keys_unsorted[])
| to_entries[]
| select(.value==$length).key
同样,对于“多个对象中的关键点”问题
当然,要实现时间效率,通常需要进行时空权衡。谢谢!我找到了实现这一目标的方法(某种程度上)。但是你的解决方案要好得多!!
# The intersection of an arbitrary number of sorted arrays
def intersection_of_sorted_arrays:
# intersecting/1 returns a stream
def intersecting($A;$B):
def pop:
.[0] as $i
| .[1] as $j
| if $i == ($A|length) or $j == ($B|length) then empty
elif $A[$i] == $B[$j] then $A[$i], ([$i+1, $j+1] | pop)
elif $A[$i] < $B[$j] then [$i+1, $j] | pop
else [$i, $j+1] | pop
end;
[0,0] | pop;
reduce .[1:][] as $x (.[0]; [intersecting(.; $x)]);
[.[] | keys] | intersection_of_sorted_arrays
def bow(stream):
reduce stream as $word ({}; .[$word|tostring] += 1);
length as $length
| bow(.[] | keys_unsorted[])
| to_entries[]
| select(.value==$length).key