My input json file:
{ "london": [ "x", 0 ] }
{ "london": [ "y", 97 ] }
{ "paris": [ "x", 15 ] }
{ "paris": [ "y", 8 ] }
I try to group by key and make the output:
{ "london": ["x", 0], ["y", 97] },
{ "paris": ["x", 15], ["y", 8] }
or:
{ "london": [ {"x", 0}, {"y", 97} ] },
{ "paris": [ {"x", 15}, {"y", 8} ] }
The following command give me an error message:
jq -s 'group_by(keys_unsorted[0]) | map({(.[0]): map(.[1])})'
jq: error (at :4): Cannot index object with number
I try to change the numbers to strings, but, it does not help. I guess that I missed something in the map (?)
EDIT:
Extantion regarding the answer from @pmf. The Original source is:
{
"city": "london",
"zoo": [
{ "room": { "name": "x" }, "gpu": { "id": "fish", "sum": 0 } },
{ "room": { "name": "y" }, "gpu": { "id": "zebra", "sum": 97 } }
]
}
{
"city": "paris",
"zoo": [
{ "room": { "name": "x" }, "gpu": { "id": "fish", "sum": 15 } },
{ "room": { "name": "y" }, "gpu": { "id": "zebra", "sum": 8 } }
]
}
and I try to get the output as above. I started with following:
jq -c '.city as $j | foreach .zoo[] as $i (.; .; {($j): [$i.room.name, $i.gpu.sum]})'
then i stuck and @pmf helped me. Can I do it else?
Your expected outputs aren't valid JSON (either they lack array brackets, or they have abundant commas). The first of the two even lists multiple values to a single object key, which is not possible (unless the value is enclosed within array brackets). Here's how to start collecting from a stream:
jq -n 'reduce (inputs | to_entries)[] as $e ({}; .[$e.key] += [$e.value])'
{
"london": [
[
"x",
0
],
[
"y",
97
]
],
"paris": [
[
"x",
15
],
[
"y",
8
]
]
}
From here, decide what your (valid) target structure should look like, and, if needed, ask another question based on that.
Edit 1: Your approach using group_by
relies on the premise that each input object consists of just one key. If you want to pursue that approach, create objects with each first of a group's first key:
jq -sc 'group_by(keys_unsorted[])[] | {(.[0] | keys_unsorted[]): [.[][]]}'
{"london":[["x",0],["y",97]]}
{"paris":[["x",15],["y",8]]}
Edit 2: Your original filter can be simplified to {(.city): (.zoo[] | [.room.name, .gpu.sum])}
(Demo), which then can be concatenated with this post's first approach by replacing inputs
with the above (Demo), which in turn can be simplified (quite similarly to the previous simplification) by not generating objects to just destructure them again, but by directly operating on the original input data instead:
jq -c '{(.city): .zoo | map([.room.name, .gpu.sum])}'
{"london":[["x",0],["y",97]]}
{"paris":[["x",15],["y",8]]}