如何筛选包含其他数组元素的任何数组元素?

huangapple go评论64阅读模式
英文:

How to filter any array elements if they contains other array elements?

问题

[
  {
    "val": 1,
    "name": "a"
  },
  {
    "val": 2,
    "name": "b"
  },
  {
    "val": 3,
    "name": "c"
  }
]

我想向jq传递一个以空格分隔的参数,并仅筛选这些元素中的名称与参数元素之一匹配的元素。以下不起作用,我不明白为什么 - 它只过滤第一个元素。我怀疑$input没有更新。我不知道如何"连接流"以使同时使用两个流成为可能 - 一个流是输入,另一个是$names | split(" ")

jq -r --arg names 'a c' '.[] | select(. as $input | $names | split(" ") | index($input.name) == 0)' 1.json

我有jq-1.5可用。

英文:

Consider the following json:

[
  {
    "val": 1,
    "name": "a"
  },
  {
    "val": 2,
    "name": "b"
  },
  {
    "val": 3,
    "name": "c"
  }
]

I want to pass an argument of space separated elements to jq and filter only these elements that have names matching to one of the argument elements. The following does not work, and I do not understand why - it only filters the first element. I suspect that $input is not updated. I do not know how to "join streams" to make it possible to use both streams at the same time - I have one stream the input and another is $names | split(" ").

$ jq -r --arg names 'a c' '.[] | select(. as $input | $names | split(" ") | index($input.name) == 0)' 1.json 
{
  "val": 1,
  "name": "a"
}

I have jq-1.5 available.

答案1

得分: 1

你可以使用IN(或any,对于 jq < 1.6)进行比较,例如:

# jq 1.6
jq --arg names 'a c' '.[] | select(IN(.name; ($names / " ")))'

# jq 1.5
jq --arg names 'a c' '.[] | select(any(.name == ($names / " "); .))'

如果你的搜索关键字是唯一的,你也可以建立一个INDEX,并查找字段:

# jq 1.6
jq --arg names 'a c' 'INDEX(.name)[($names / " ")]'

# jq 1.5
jq --arg names 'a c' 'map({key:.name, value:.}) | from_entries[($names / " ")]'

输出:

{
  "a": 1,
  "name": "a"
}
{
  "c": 3,
  "name": "c"
}
英文:

You can make the comparison using IN (or any for jq < 1.6), for example:

# jq 1.6
jq --arg names &#39;a c&#39; &#39;.[] | select(IN(.name; ($names / &quot; &quot;)[]))&#39;

# jq 1.5
jq --arg names &#39;a c&#39; &#39;.[] | select(any(.name == ($names / &quot; &quot;)[]; .))&#39;

If your search keys are unique, you could also build up an INDEX, and lookup the fields:

# jq 1.6
jq --arg names &#39;a c&#39; &#39;INDEX(.name)[($names / &quot; &quot;)[]]&#39;

# jq 1.5
jq --arg names &#39;a c&#39; &#39;map({key:.name, value:.}) | from_entries[($names / &quot; &quot;)[]]&#39;

Output:

{
  &quot;a&quot;: 1,
  &quot;name&quot;: &quot;a&quot;
}
{
  &quot;c&quot;: 3,
  &quot;name&quot;: &quot;c&quot;
}

答案2

得分: 1

最简单的方法可能是先将您的 names 拆分成一个数组,然后使用 IN 来过滤您的数据流:

jq -r --arg names 'a c' '($names | split(" ")) as $names | .[] | select(.name | IN($names[]))'

或者使用 any

jq -r --arg names 'a c' '($names | split(" ")) as $names | .[] | select(any(.name == $names[]; .))'

(后者只是内联了 INdef IN(s): any(s == .; .);

英文:

Easiest is probably to split your names into an array first, then use IN to filter your stream:

jq -r --arg names &#39;a c&#39; &#39;($names/&quot; &quot;) as $names
| .[] | select(.name | IN($names[]))&#39;

Or using any:

jq -r --arg names &#39;a c&#39; &#39;($names/&quot; &quot;) as $names
| .[] | select(any(.name == $names[]; .))&#39;

(the latter simply inlines IN: def IN(s): any(s == .; .);)

huangapple
  • 本文由 发表于 2023年3月7日 17:58:32
  • 转载请务必保留本文链接:https://go.coder-hub.com/75660442.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定