JQ query to filter entries using a membership condition over an external array passed into parameter (with --arg)

100 Views Asked by At

Given a test file test.json:

[
  {
    "name": "foo",
    "key1": "val3,val2,val1",
    "category": "thefoocategory"
  },
  {
    "name": "bar",
    "key1": "val2",
    "category": "thebarcategory"
  }
]

and given:

str="val1,val2,val3"

I want to filter from the file the "name" attributes for which the associated "key1" attribute, seen as an array, hold all the values (order of elements doesn't matter) of "str" seen as an array [foo]

I try with easier use cases (replacing "valX" by "X" in the test file) but I am stuck at specifying the condition of membership.

Something like:

cat test1 | jq -r --arg v "1,2,3" '[.[] | select($v | split(",") | all((.key1 | split(",")) | index(.) != null))]'

It fails (Cannot index string with string "key1") but I can't really figure out why replacing (.key1|split(",")) with [1,2,3] produces a result.

2

There are 2 best solutions below

9
pmf On

You could split the list at commas into an array, then use all with IN to test the containedness for all items.

str="val1,val2,val3"
jq --arg str "$str" '($str / ",") as $arr
  | map(select(. as $dot | $arr | all(IN(($dot.key1 / ",")[]))).name)
'
[
  "foo"
]

Demo

3
peak On

For clarity, I'd use all/2:

jq -r --arg v "val1,val2,val3" '
   ($v / ",") as $values
   | .[]
   | select( (.key1 / ",") as $kv
             | all( $values[]; IN($kv[]) ))
   | .name