Reputation: 421090
I have input like this:
{ "prop": ["apple", "banana"] }
{ "prop": ["kiwi", "banana"] }
{ "prop": ["cherry", "orange"] }
How do I print objects where prop contains at least one of kiwi and orange?
(The list of interesting values is longer than just 2, so I'd like to leverage the any
function somehow.)
I've tried the following
jq 'select(any(.prop[] | contains(["kiwi", "orange"])))' < input.json
and various variants of the above, but can't figure out the right expressions.
Upvotes: 2
Views: 2966
Reputation: 1970
The above answers worked for me in jq 1.7, but they failed in jq 1.6 (which is what's preinstalled on a GitHub Actions ubuntu-latest runner in February 2024, and I don't want the performance hit of installing something better during every CI run).
Here's what I came up with that works correctly and consistently in both 1.6 and 1.7:
def intersects(a; b):
any(a[] as $aElem | b | index($aElem));
Use as follows:
intersects(["a", "b", "c"]; ["c", "d", "e"]) # true
or
intersects(["a", "b", "c"]; ["d", "e", "f"]) # false
Upvotes: 0
Reputation: 116870
The stream-oriented version of the built-in function any
can be most easily used if one bears in mind its signature:
def any(generator; condition):
So we are led to:
select( any( .prop[]; . == "kiwi" or . == "orange" ))
or more succinctly:
select( any(.prop[]; IN("kiwi", "orange")))
If the values of interest are provided as a JSON array, say $whitelist, you could tweak the above by substituting $whitelist[]
for the explicit stream of values:
select( any(.prop[]; IN($whitelist[]) ))
Upvotes: 4
Reputation: 50785
I think you're looking for IN/2
. It's implemented using any
, but is far easier to grasp.
select(IN(.prop[]; "kiwi", "orange"))
Upvotes: 2