I've got a more complex JQ expression that's handling an array of objects.
The input looks like this:
[
    { "key": "1", "value": "value 1"},
    { "key": "2", "value": "value 2"},
    { "key": "1", "value": "value 3"},
]
What I want to get is this:
{
    "1": { "values": ["value 1", "value 3"] },
    "2": { "values": ["value 2"] }
}
or, for my use case:
{
    "1": [ "value 1", "value 3" ],
    "2": [ "value 2" ]
}
would also be OK.
I've already tried to use … | { (.key): [.value] } but the result is (to no real surprise to me) that later occurrences of keys simply overwrite already existing ones. What I want to accomplish is something like "create a new key/value pair or add .value to an already existing one's 'values' array".
The drawback of a solution relying on group_by is that group_by requires a sort, which is unnecessary here.  In this response, I'll show how to avoid any sorting by using a generic (and generally useful) jq function that "melds" an array of JSON objects, essentially by popping the value at each key into an array, and then concatenating corresponding arrays.
# input should be an array of objects
def meld:
  reduce .[] as $o
    ({}; reduce ($o|keys)[] as $key (.; .[$key] += [$o[$key]] ));
Let's also define some data:
def data:
[
    { "key": "1", "value": "value 1"},
    { "key": "2", "value": "value 2"},
    { "key": "1", "value": "value 3"}
]
;
Then the filter:
data |  map([.] | from_entries) | meld
produces:
{"1":["value 1","value 3"],"2":["value 2"]}
                        OK, after finally finding out what I wanted I also understand that my previous filters didn't keep the input array but resulted in objects being output after each other. So that was basically the reason why all examples I found wouldn't work.
I wanted to group by keys (hence the key/value requirement), which group_by already does, but wouldn't work.
From grouping working its only a small step to my solution (unique keys, values in arrays).
'… group_by(.key) | map({ "key": .[0].key, "values": map(.value) | unique })'
The output now looks like this, which is perfectly fine for my requirements:
[
    {
        "key": "1",
        "values": [
            "value 1",
            "value 3"
        ],
    },
    {
        "key": "2",
        "values": [
            "value 2"
        ]
    }
]
                        If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With