I have a JSON file with a bunch of objects and after each, there's a smaller object with extra data. They don't share any information, so the position is the only thing connecting them. This unfortunate structure is due to limitations of OverpassQL.
The challenge is how to merge each pair in the input, e.g. in the simpler case ["a","b","c","d"]
to ["ab","cd"]
.
If I put it all in a scripted loop outside of jq and reconstructed the JSON afterwards, something as simple as this would work (but it'd be quite lame):
$ jq '.elements[0] + .elements[1]' test.json
So I generated the indices to then use them in the original data:
$ jq -n 'range(0; 2) | foreach . as $idx (0; $idx; [2 * $idx, 2 * $idx + 1])'
[
0,
1
]
[
2,
3
]
But combining the two still only gives me the first pair. If I use input
instead, it also prints an error on exit. A simplified version:
$ jq -n 'range(0; 2) |
foreach . as $idx (0; $idx; inputs |
nth(2 * $idx; .[]) + nth(2 * $idx + 1; .[]))' <<< '["a","b","c","d"]'
"ab"
I tried a few other things, but to no avail. Is there a way to merge all consecutive objects in just jq
?
The challenge is how to merge each pair in the input, e.g. in the simpler case
["a","b","c","d"]
to["ab","cd"]
.
So your input is an array, and you want to process every two items into a new item. You can use the undocumented _nwise
function. Applied by itself using an item count of 2
, you get ["a","b"] ["c","d"]
, so wrap this stream into an array, and use add
to process the strings in the two items into one:
jq '[_nwise(2) | add]' <<< '["a","b","c","d"]'
[
"ab",
"cd"
]
If you're uncomfortable with undocumented functions, you can replicate its behavior using a while
loop, that reduces the array by two items until there aren't any left, and slice each subarray further to only contain the first two items:
jq '[while(length > 0; .[2:])[:2] | add]' <<< '["a","b","c","d"]'