Reputation: 13
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
Reputation: 24802
You can use the following :
map(to_entries) | add | group_by(.key) | map({ key: (.[0].key), value:([.[].value | add]) }) | from_entries
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
Reputation: 50750
Using nested reduce
s:
reduce inputs as $in (.;
reduce ($in | keys_unsorted[]) as $k (.;
.[$k] += $in[$k]
)
)
Upvotes: 2