'How to limit properties of a JSON object given array of property names using JQ?

Assuming I have the following JSON object (which is just an example):

{ 
  "foo": 1, 
  "bar": 2, 
  "baz": 3 
}

And the following JSON array (another example):

["foo", "baz"]

How could I use jq to output the following object?

{ 
  "foo": 1, 
  "baz": 3 
}

I hate asking this question because I feel certain it has been answered before, but google has failed me and my jq-fu is just not where it needs to be to figure this out.



Solution 1:[1]

Provided that . is the object and $arr is the array, the following does the trick

delpaths(keys - $arr | map([.]))

Solution 2:[2]

Using a reduce to iteratively build up the result object would be one way:

echo '["foo", "baz"]' | jq --argjson index '{"foo":1,"bar":2,"baz":3}' '
  reduce .[] as $x ({}; .[$x] = $index[$x])
'

Using JOIN, creating key-value pairs, and employing from_entries for assembly would be another way:

echo '["baz", "foo"]' | jq --argjson index '{"foo":1,"bar":2,"baz":3}' '
  JOIN($index; .) | map({key:.[0], value:.[1]}) | from_entries
'

Output:

{
  "foo": 1,
  "baz": 3
}

Solution 3:[3]

To achieve the desired result, one could write:

 jq '{foo, baz}'

This can (with some considerable trepidation) be made into a solution for the given problem by text wrangling, e.g. along the lines of:

jq "$(echo '["foo", "baz"]' | jq -Rr '"{" + .[1:-1] + "}" ')"

or

jq "$(echo '["foo", "baz"]' | sed -e 's/\[/{/' -e 's/\]/}/')"

Solution 4:[4]

Here's a reduce-free solution that assumes $keys is the array of keys of interest and that is possibly more efficient than the one involving array subtraction:

. as $in | INDEX( $keys[]; $in[.] )

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 oguz ismail
Solution 2
Solution 3
Solution 4