10

If I have an object with two arrays containing unique values in it

{"all":["A","B","C","ABC"],"some":["B","C"]}

How can I find .all - .some?

In this case I am looking for ["A","ABC"]

Jon
  • 1,785
  • 2
  • 19
  • 33

3 Answers3

16

@Jeff Mercado blew my mind! I didn't know array subtraction was allowed...

echo -n '{"all":["A","B","C","ABC"],"some":["B","C"]}' | jq '.all-.some'

yields

[
  "A",
  "ABC"
]
Jon
  • 1,785
  • 2
  • 19
  • 33
4

I was looking for a similar solution but with the requirement that the arrays were being generated dynamically. Below solution just does the expected

array1=$(jq -e '')  // jq expression goes here
array2=$(jq -e '')  // jq expression goes here

array_diff=$(jq -n --argjson array1 "$array1" --argjson array2 "$array2" 
'{"all": $array1,"some":$array2} | .all-.some' )
manikantan
  • 41
  • 1
1

While - Array Subtraction is the best approach for this, here is another solution using del and indices:

. as $d | .all | del(.[ indices($d.some[])[] ])

It may be of help when you want to know which elements were removed. For example with the sample data and the -c (compact output) option, the following filter

  . as $d
| .all
| [indices($d.some[])[]] as $found
| del(.[ $found[] ])
| "all", $d.all, "some", $d.some, "removing indices", $found, "result", .

produces

"all"
["A","B","C","ABC"]
"some"
["B","C"]
"removing indices"
[1,2]
"result"
["A","ABC"]
jq170727
  • 13,159
  • 3
  • 46
  • 56