How to check if element exists in array with jq
I have an array and I need to check if elements exists in that array or to get that element from the array using jq, fruit.json:
{
"fruit": [
"apple",
"orange",
"pomegranate",
"apricot",
"mango"
]
}
cat fruit.json | jq '.fruit .apple'
does not work
The semantics of 'contains' is not straightforward at all. In general, it would be better to use 'index' to test if an array has a specific value, e.g.
.fruit | index( "orange" )
However, if the item of interest is itself an array, the general form:
ARRAY | index( [ITEM] )
should be used, e.g.:
[1, [2], 3] | index( [[2]] ) #=> 1
IN/1
If your jq has IN/1
then a better solution is to use it:
.fruit as $f | "orange" | IN($f[])
If your jq has first/1
(as does jq 1.5), then here is a fast definition of IN/1
to use:
def IN(s): first((s == .) // empty) // false;
any(_;_)
Another efficient alternative that is sometimes more convenient is to use any/2
, e.g.
any(.fruit[]; . == "orange")
or equivalently:
any(.fruit[] == "orange"; .)
To have jq
return success if the array fruit
contains "apple"
, and error otherwise:
jq -e '.fruit|any(. == "apple")' fruit.json >/dev/null
To output the element(s) found, change to
jq -e '.fruit[]|select(. == "apple")' fruit.json
If searching for a fixed string, this isn't very relevant, but it might be if the select
expression might match different values, e.g. if it's a regexp.
To output only distinct values, pass the results to unique
.
jq '[.fruit[]|select(match("^app"))]|unique' fruit.json
will search for all fruits starting with app
, and output unique values. (Note that the original expression had to be wrapped in []
in order to be passed to unique
.)
[WARNING: SEE THE COMMENTS AND ALTERNATIVE ANSWERS.]
cat fruit.json | jq '.fruit | contains(["orange"])'