in reply to Re^2: Syntactically cool list of lists
in thread Syntactically cool list of lists

True, or we can avoid generating the elements in the first place:
sub groups_of_n { sub min { return $_[0] < $_[1] ? $_[0] : $_[1]; } my $n = shift; return map { [ @_[$_*$n..min($_*$n+$n-1,$#_)]] } 0..$#_/$n; }

Replies are listed 'Best First'.
Re^4: Syntactically cool list of lists
by TimToady (Parson) on Dec 22, 2006 at 17:42 UTC
    Or in Perl 6:
    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; }