Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/json/15.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
使用jq在JSON对象中查找公共键_Json_Key_Jq_Set Intersection - Fatal编程技术网

使用jq在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

我试图在Json文件中查找所有公共密钥,因为我们不知道文件中的密钥名称

Json文件如下所示:

{
   "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