Reputation: 392
A little more sophisticated as my previous question. Missing indexes mess things up too.
Input:
{
"a": [
{ "b": 1, "d": "p" },
{ "b": 3, "d": "r" },
{ "b": 4, "d": "s" }
],
"h": [
{ "b": 1, "i": "k" },
{ "b": 2, "i": "l" },
{ "b": 4, "i": "n" }
]
}
Desired output:
{
"q": [
{ "b": 1, "d": "p", "i": "k" },
{ "b": 2, "i": "l" },
{ "b": 3, "d": "r" },
{ "b": 4, "d": "s", "i": "n" }
]
}
Tried:
jq '[.a, .h ] | transpose | map(add)| {l: .}'
jq '[ .a[] , .h[] ] | unique_by(.b) | { l: sort_by(.b) }'
jq '[ .a[] + .h[] ] | unique_by(.b) | { l: sort_by(.b) }'
jq '[ .a[] * .h[] ] | unique_by(.b) | { l: sort_by(.b) }'
Upvotes: 1
Views: 3117
Reputation: 116740
Here's a solution using the generic function aggregate_by
, defined as follows:
def aggregate_by(s; f; g):
reduce s as $x (null; .[$x|f] += [$x|g]);
First, notice that with this def:
aggregate_by(.a[], .h[]; .b|tostring; .)[]
| add
produces the desired array except for the ordering of elements. If the ordering of elements in the output array is unimportant, then the above could be tweaked to provide a simple solution that does not involve group_by
, which entails sorting.
To produce the desired (sorted-by-b) output, we could tweak the above as follows:
{q: [aggregate_by(.a[], .h[]; .b|tostring; .)[]]
| map(add)
| sort_by(.b) }
Upvotes: 1
Reputation: 50750
Use group_by
to group array elements by a filter's output (.b
in this case):
jq '{ q : [ add | group_by(.b)[] | add ] }' file
Upvotes: 2