heyarne
heyarne

Reputation: 1167

Map over two arrays with jq and merge objects inside

I have two arrays of identical length with objects in them:

input: [[{foo: 1}, {foo: 23}], [{bar: 12, baz: 543}, {bar: -1}]]

How do I tell jq to merge them into one array like below?

output: [{foo: 1, bar: 12, baz: 543}, {foo: 23, bar: -1}]

Upvotes: 2

Views: 1446

Answers (2)

peak
peak

Reputation: 116957

Here is a stream-oriented solution using zips/2 defined as follows:

# Input: an array, padded as necessary with null.
# Output: a stream with |stream| items, `[$in[$i], $s$i] | f`, 
# where $s$i is the $i-th item in the stream.
def zips(stream; f):
  . as $in | foreach stream as $x (-1; .+=1; [$in[.], $x] | f);

This avoids the overhead of transpose, and would be especially appropriate if the two arrays had not already been combined, or if a stream output was acceptable.

In any case, zips could be used as follows to solve the problem at hand:

. as $in
| $in[0] | [zips( $in[1][]; add )]

If you don't require the result to be a single array, you can omit the square brackets around the call to zips.

Upvotes: 1

jq170727
jq170727

Reputation: 14715

Here is a solution which uses transpose and add. Assuming the sample data is in data.json:

$ jq -M 'transpose|map(add)' data.json
[
  {
    "foo": 1,
    "bar": 12,
    "baz": 543
  },
  {
    "foo": 23,
    "bar": -1
  }
]

Try it online at jqplay.org

Upvotes: 3

Related Questions