Error 418
Error 418

Reputation: 13

Merge arrays under same key

I have two files containing objects. The fields of each object are arrays of objects. I would like to merge the object arrays by each key.

I tried getting a list of all keys by jq -s '.[0] * .[1] | to_entries[].key ' file1.json file2.json. I 'm not sure how you would match the keys from .[1] to .[0] once you have captured the object arrays.

file1.json

{
    "foo": [
        {
            "nested": "object"
        }
    ],
    "bar": [
        {
            "nested": "object.bar"
        }
    ]

}

file2.json

{
    "foo": [
        {
            "nested": "object.foo2"
        }
    ],
    "baz": [
        {
            "nested": "object.baz"
        }
    ]

}

merged.json

{
    "foo": [
        {
            "nested": "object"
        },
        {
            "nested": "object.foo2"
        },

    ]
    "bar": [
        {
            "nested": "object.bar"
        }
    ]
    "baz": [
        {
            "nested": "object.baz"
        }
    ]

}

Upvotes: 1

Views: 793

Answers (2)

Aaron
Aaron

Reputation: 24802

You can use the following :

map(to_entries) | add | group_by(.key) | map({ key: (.[0].key), value:([.[].value | add]) }) | from_entries

Try it here.

map(to_entries) change each of your files into an array of key/value pairs.

add merge those two arrays into one.

group_by(.key) changes the content of the array into multiple arrays that regroup the objects with the same key.

map({ key: (.[0].key), value:([.[].value | add]) }) transforms those arrays into an object with a key/value pair whose key is the original key and the value is the merged values of the different objects with that key.

from_entries recreates an object from the array of key/value objects.

Upvotes: 3

oguz ismail
oguz ismail

Reputation: 50750

Using nested reduces:

reduce inputs as $in (.;
  reduce ($in | keys_unsorted[]) as $k (.;
    .[$k] += $in[$k]
  )
)

jqplay demo

Upvotes: 2

Related Questions