in reply to Elegance, dammit!

In real life, I would normally use a splice like Errto and jdporter.

Before *any* solution, I would put:

die if @ref / 3;

Most elegant, non-destructive Perl5 solution I could think of:

my %out = map { $ref[$_] => [ @ref[$_+1..$_+2] ] } grep { not $_ % 3 } 0 .. $#ref;

Even better, but requires Perl6:

for @ref -> $key, $val1, $val2 { %out{$key} = [ $val1, $val2 ]; }

Update: Better yet, this also works in Perl6:

my %out = map -> $k, $v, $w { $k => [ $v, $w ]; }, @ref;

Replies are listed 'Best First'.
Re^2: Elegance, dammit!
by oko1 (Deacon) on Jun 16, 2007 at 02:58 UTC

    Ah-HAH! :)

    (I *really* liked that Perl6 solution, BTW; I see that I'm going to have to get off my lazy butt and dig into it.)

    All of that - particularly Util's solution - has finally caused a reticent neuron to fire. Originally, I thought of this:

    $out{shift @ref} = [splice @ref,0,2] while @ref;

    ...but there's a precedence problem with that, so that %out ends up containing stuff like

    2 => [ 0, 1 ], 5 => [ 3, 4 ] etc.

    so my final cut at it ends up being this:

    die if @ref % 3; $out{$a} = [splice @ref,0,2] while $a = shift @ref;

    I'm definitely up for seeing more solutions, though. You folks come up with some very pretty thought patterns. :)

    Thank you all!

Re^2: Elegance, dammit!
by moritz (Cardinal) on Jun 16, 2007 at 09:10 UTC
    I can't resist offering a shorter Perl 6-solution:

    my %out = map {$^k => [$^v, $^w]}, @ref;

    The ^ secondary sigil ("twigil") is a self declaring formal paramter, all of the variables starting with $^ will be filled in the block in lexicographic order.

Re^2: Elegance, dammit!
by kyle (Abbot) on Jun 16, 2007 at 19:30 UTC

    die if @ref / 3;

    I really like the idea of an assertion (especially during debugging), but I'd probably write it this way:

    die 'Assertion failed: @ref not divisible by 3' if scalar @ref % 3;

    If I'm not mistaken, yours dies every time @ref has any elements.