英文:
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 'a c' '.[] | select(IN(.name; ($names / " ")[]))'
# jq 1.5
jq --arg names 'a c' '.[] | select(any(.name == ($names / " ")[]; .))'
If your search keys are unique, you could also build up an INDEX
, and lookup the fields:
# 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 / " ")[]]'
Output:
{
"a": 1,
"name": "a"
}
{
"c": 3,
"name": "c"
}
答案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[]; .))'
(后者只是内联了 IN
:def 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 'a c' '($names/" ") as $names
| .[] | select(.name | IN($names[]))'
Or using any
:
jq -r --arg names 'a c' '($names/" ") as $names
| .[] | select(any(.name == $names[]; .))'
(the latter simply inlines IN
: def IN(s): any(s == .; .);
)
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论