简体   繁体   中英

jq 1.5 print items from array that is inside another array

Incoming json file contains json array per row eg:

["a100","a101","a102","a103","a104","a105","a106","a107","a108"]
["a100","a102","a103","a106","a107","a108"]
["a100","a99"]
["a107","a108"]

a "filter array" would be ["a99","a101","a108"] so I can slurpfile it

Trying to figure out how to print only values that are inside "filter array", eg the output:

["a101","a108"]
["a108"]
["a99"]
["a108"]

You can port IN function from jq 1.6 to 1.5 and use:

def IN(s): any(s == .; .);
map(select(IN($filter_array[])))

Or even shorter:

map(select(any($filter_array[]==.;.)))

I might be missing some simpler solution, but the following works :

map(select(. as $in | ["a99","a101","a108"] | contains([$in])))

Replace the ["a99","a101","a108"] hardcoded array by your slurped variable.

You can try it here !

In the example, the arrays in the input stream are sorted (in jq's sort order), so it is worth noting that in such cases, a more efficient solution is possible using the bsearch built-in, or perhaps even better, the definition of intersection/2 given at https://rosettacode.org/wiki/Set#Finite_Sets_of_JSON_Entities

For ease of reference, here it is:

def intersection($A;$B):
  def pop:
    .[0] as $i
    | .[1] as $j
    | if $i == ($A|length) or $j == ($B|length) then empty
      elif $A[$i] == $B[$j] then $A[$i], ([$i+1, $j+1] | pop)
      elif $A[$i] <  $B[$j] then [$i+1, $j] | pop
      else [$i, $j+1] | pop
      end;
  [[0,0] | pop];

Assuming a jq invocation such as:

jq -c --argjson filter '["a99","a101","a108"]' -f intersections.jq input.json

an appropriate filter would be:

($filter | sort) as $sorted
| intersection(.; $sorted)

(Of course if $filter is already presented in jq's sort order, then the initial sort can be skipped, or replaced by a check.)

Output

["a101","a108"]
["a108"]
["a99"]
["a108"]

Unsorted arrays

In practice, jq's builtin sort filter is usually so fast that it might be worthwhile simply sorting the arrays in order to use intersection as defined above.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM