http://qs321.pair.com?node_id=908012


in reply to Processing pairs of values from even-sized array

I'd normally use a slightly simpler version of JohnGG's splice approach. Something like

my @arr = qw/1 2 3 4 5 6 7 8/; while(my ($x,$y) = splice @arr,0,2) { say "$x => $y"; }

Something I've needed in the past was to get two arrays (odds and evens). Grep can do this. You could combine them into a hash thus:

my @arr = qw/1 2 3 4 5 6 7 8/; my ($j,$i)=(0,0); my ($x,$y) = ([grep { ++$i % 2} @arr] , [grep {$j++ % 2} @arr]); my %hash; @hash{@{$x}}=@{$y}; for(keys %hash) { say "$_ => $hash{$_}" }
Gives us:
1 => 2 3 => 4 7 => 8 5 => 6
Or you could iterate them (which is safer if some x may be undef)
my @arr = qw/1 2 3 4 5 6 7 8/; push @arr, undef; push @arr, 9; my ($j,$i)=(0,0); my ($x,$y) = ([grep { ++$i % 2} @arr] , [grep {$j++ % 2} @arr]); $i=0; for(@{$x}){ say $_ ." => " . $y->[$i++] if($_); }
Obviously that doesn't scale to big arrays. I'm sure List::MoreUtils is always the better approach.



Replies are listed 'Best First'.
Re^2: Processing pairs of values from even-sized array
by johngg (Canon) on Jun 03, 2011 at 21:54 UTC
    Something I've needed in the past was to get two arrays (odds and evens).

    You can also push onto two arrays using a ternary.

    knoppix@Microknoppix:~$ perl -E ' > push @{ $_ % 2 ? \ @odds : \ @evens }, $_ for 1 .. 8; > say qq{ Odds : @odds}; > say qq{Evens : @evens};' Odds : 1 3 5 7 Evens : 2 4 6 8 knoppix@Microknoppix:~$

    I hope this is of interest.

    Cheers,

    JohnGG

      List::MoreUtils also has  part to do similar things:

      >perl -wMstrict -le "use List::MoreUtils qw(part); use Data::Dumper; ;; my $i; my @parts = part { ++$i % 2 } 1 .. 8; ;; print Dumper \@parts; " $VAR1 = [ [ 2, 4, 6, 8 ], [ 1, 3, 5, 7 ] ];

        Thank you for pointing that out, I rarely come across List::MoreUtils as it is not a core module so I wasn't aware of part. Very useful if you can work with the resulting AoA but it seems a bit awkward if you really do need separate arrays.

        knoppix@Microknoppix:~$ perl -MList::MoreUtils=part -E ' > @parts = part { > ++ $i; > $i % 5 > ? $i % 2 > ? 0 > : 1 > : 2 > } 1 .. 20; > @odds = @{ $parts[ 0 ] }; > @evens = @{ $parts[ 1 ] }; > @fivers = @{ $parts[ 2 ] }; > say qq{@odds}; > say qq{@evens}; > say qq{@fivers};' 1 3 7 9 11 13 17 19 2 4 6 8 12 14 16 18 5 10 15 20 knoppix@Microknoppix:~$
        knoppix@Microknoppix:~$ perl -E ' > push @{ > $_ % 5 > ? $_ % 2 > ? \ @odds > : \ @evens > : \ @fivers > }, $_ for 1 .. 20; > say qq{@odds}; > say qq{@evens}; > say qq{@fivers};' 1 3 7 9 11 13 17 19 2 4 6 8 12 14 16 18 5 10 15 20 knoppix@Microknoppix:~$

        Perhaps I'm missing something. I have tried pushing references to @odds etc. onto @parts before using part without success so I can't seem get away from having to do @odds = @{ $parts[ 0 ] }; etc.

        Cheers,

        JohnGG