How to check if element exists in array with jq
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
.)