sub groups_of_n ($n,*@a) {
return map { [ @a[$_ + ^$n]:v ] }, ^@a:by($n);
}
This factors out the multiplications by using a step of $n on
the initial range. We've also made use of unary ^, which is short for 0..^, that is, "all the numbers up to but not including this number."
Unfortunately pugs does not yet implement :v for existing values or :by for range stepping, and we only just changed the semantics of ranges to allow scalar operators to return modified ranges, so that's not implemented yet either. But here's a version that works in pugs today:
sub groups_of_n ($n,*@a) {
return map { [ @a[$_ ..^ min($_+$n,+@a)]] }, (0..@a.end/$n) »*« $n;
}
This also factors out all the multiplications, but this time by hyper multiplying the range we feed to map. Inside the subscript it makes use of the ..^ notation to exclude the endpoint without having to subtract 1. Note that min is a built-in in Perl 6. Also note that map now requires a comma after the block, one of many grammar regularizations in Perl 6.
Actually, there are a couple things that will break in that last example, because min is turning into an infix, and the listop form would have to be written as a reduce operator. Also, dwimmy hypers require you to aim the small end of the French quote at the argument to be dwimmed, so once pugs catches up with those spec changes you'd probably end up writing that last example as:
sub groups_of_n ($n,*@a) {
return map { [ @a[$_ ..^ ($_+$n min +@a)]] }, (0..@a.end/$n) »*» $n;
}
|