Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/.htaccess/6.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
Json jq:从对象中选择关键帧的子集_Json_Select_Key_Subset_Jq - Fatal编程技术网

Json jq:从对象中选择关键帧的子集

Json jq:从对象中选择关键帧的子集,json,select,key,subset,jq,Json,Select,Key,Subset,Jq,给定一个数组中键的json输入字符串,返回一个对象,其中只包含原始对象和输入数组中有键的条目 我有一个解决方案,但我认为它并不优雅({($k):$input[$k]}感觉特别笨重……),这是我学习的机会 jq -n '{"1":"a","2":"b","3":"c"}' \ | jq --arg keys '["1","3","4"]' \ '. as $input | ( $keys | fromjson ) | map( . as $k

给定一个数组中键的json输入字符串,返回一个对象,其中只包含原始对象和输入数组中有键的条目

我有一个解决方案,但我认为它并不优雅(
{($k):$input[$k]}
感觉特别笨重……),这是我学习的机会

jq -n '{"1":"a","2":"b","3":"c"}'   \
    | jq --arg keys '["1","3","4"]' \
    '. as $input 
     | ( $keys | fromjson )
     | map( . as $k
          | $input
          | select(has($k))
          | {($k):$input[$k]}
          )
     | add'
你知道怎么清理吗


我觉得这是一个很好的起点,但我无法让它发挥作用。

您可以使用此过滤器:

with_entries(
    select(
        .key as $k | any($keys | fromjson[]; . == $k)
    )
)

这里有一些额外的澄清

对于输入对象
{“key1”:1,“key2”:2,“key3”:3}
我想删除不在所需键集中的所有键
[“key1”,“key3”,“key4”]

with_entries
{“key1”:1,“key2”:2,“key3”:3}
转换为以下键值对数组,并将select语句映射到数组上,然后将生成的数组转换回对象

这是
语句中带有_entries
的内部对象

[
  {
    "key": "key1",
    "value": 1
  },
  {
    "key": "key2",
    "value": 2
  },
  {
    "key": "key3",
    "value": 3
  }
]
然后,我们可以从该数组中选择符合条件的键

这就是魔法发生的地方。。。下面是这个命令的中间部分。下面的命令获取扩展的值数组,并将它们转换为可以从中选择的对象列表

jq -cn '{"key":"key1","value":1}, {"key":"key2","value":2}, {"key":"key3","value":3}
      | select(.key == ("key1", "key3", "key4"))'
这将产生以下结果

{"key":"key1","value":1}
{"key":"key3","value":3}
with entries命令可能有点棘手,但很容易记住,它需要一个过滤器,定义如下

def with_entries(f): to_entries|map(f)|from_entries;
这和

def with_entries(f): [to_entries[] | f] | from_entries;
另一个让人困惑的问题是
=

考虑以下命令。我们看到输出是所有左手列表和右手列表的外部产物

jq -cn '1,2,3| . == (1,1,3)'
true
true
false
false
false
false
false
false
true
如果该谓词位于select语句中,则当谓词为true时,我们保留输入。注意,您也可以在此处复制输入

jq -cn '1,2,3| select(. == (1,1,3))'
1
1
3

Jeff的回答有一些不必要的低效,这两个问题都可以通过以下方式解决,假设使用了
--argjson-keys
而不是
--arg-keys

with_entries( select( .key as $k | $keys | index($k) ) )

内部检查解决方案:

jq 'with_entries(select([.key] | inside(["key1", "key2"])))'

内部操作员大部分时间都在工作;然而,我刚刚发现内部操作符有副作用,有时它会选择不需要的键,假设输入是
{“key1”:val1,“key2”:val2,“key12”:val12}
,然后通过
内部([“key12”])
选择
“key1”
“key12”

如果需要精确匹配,请使用in运算符:这样将仅选择
.key2
.key12

jq 'with_entries(select(.key | in({"key2":1, "key12":1})))'
由于in运算符仅检查对象中的键(或数组中的索引
存在?
),因此必须以对象语法编写,将所需的键作为键,但值并不重要;in操作符的使用并不是实现此目的的完美方法,我希望Javascript ES6包含API的反向版本,以jq内置的形式实现


要检查一项
。key
是否包含
来自数组从文档中不清楚我可以通过
select(.key==(“1”、“3”、“4”)
在==语句的右侧使用()。避免遍历输入键和所需键的整个外积。这不应该是对其他答案的编辑吗?但我可以在同一个线程上有两个答案吗?只是因为有两种不同的方法你可以,但通常你想在同一个答案中对一种方法提出警告,所以在决定合适的方法之前,没有人需要阅读整个Q+A。非常相似的方法通常可以组合成一个答案。仅供参考,这将返回以
key1
key2
开头的任何条目,因此
key1234
key22
也是如此。
jq 'with_entries(select(.key | in({"key2":1, "key12":1})))'
jq 'with_entries(select(.key | included(["key2", "key12"])))'