I want to convert
[1,"a",2,"b",3,"c"]
to
[[1,"a"],[2,"b"],[3,"c"]]
The best I've come up with is (using 1.5)
[recurse(.[2:];length>1)[0:2]]
Is there a more concise or more performant or 1.4 compatible solution I could use instead?
Personally, I would have tried to do something like you did, to me that feels right from a functional perspective.
But there are other ways this could be expressed. You could take advantage of the fact that when converting an array to entries, you get an array of index/value pairs.
to_entries | group_by(.key/2 | floor) | map(map(.value))
On the other hand, you could also just create slices of the array using a range of numbers. I think this may perform better than recursing.
. as $arr | [ range(0; length/2) * 2 | $arr[.:.+2] ]
The following generalizes the task, works with jq 1.4, is highly performant with the optimizations in jq 1.5, and can be used to implement rho/1 (like R's "dim(z) <- c(3,5,100)" and APL's "A⍴B"):
# Input: an array
# Output: a stream of arrays
# If the input is [] then the output stream is empty,
# otherwise it consists of arrays of length n, each array consisting
# of successive elements from the input array, padded with nulls.
def takes(n):
def _takes:
if length == 0 then empty
elif length < n then .[n-1] = null
else .[0:n], (.[n:] | _takes)
end;
_takes;
Using "takes", one could fulfill the task using: [takes(2)]
Using "rho", there are several possibilities, notably:
[rho( [ 2 ] )]
# or:
rho([3,2])
For more about "rho", see https://github.com/stedolan/jq/issues/829
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