Beefy Boxes and Bandwidth Generously Provided by pair Networks
Your skill will accomplish
what the force of many cannot
 
PerlMonks  

How do I loop through a list two or more elements at a time?

( #121066=categorized question: print w/ replies, xml ) Need Help??
Contributed by moodster on Oct 24, 2001 at 14:27 UTC
Q&A  > arrays


Description:

If I have a list like this one:
@list = qw( a b c d e f );
I can easily loop through each element with a simple for loop like this:
for $el (@list) { print "$el\n"; }
But suppose the elements in the loop are grouped two and two and that for each loop I want to get two elements. Something like this (I know the syntax is all wrong):
for $el1, $el2 (@list) { print "$el1 - $el2\n"; }
I know there must be an easy way to do this (this being perl and all), but I can't figure it out. Anyone?

Answer: How do I loop through a list two or more elements at a time?
contributed by davorg

If you don't mind destroying your array in the process, you can use splice.

while (my ($el1, $el2) = splice(@list, 0, 2)) { # do stuff }
Answer: How do I loop through a list two or more elements at a time?
contributed by tachyon

{cough} you could always use the obvious approach with a C style loop

@ary = qw( a b c d e f g h i ); for ( my $i=0; $i<@ary; $i=$i+2 ) { print "$ary[$i] - $ary[$i+1]\n"; }
Answer: How do I loop through a list two or more elements at a time?
contributed by jeroenes

For a real answer now: create your list as an array of arrays, loop on the outer array.

print "$_->[0] - $_->[1]\n" for @LoL;

If you start with a flat list, you create the LoL with davorg's solution:

my @LoL; while(my @items = splice( @list, 0, 2) ){ push @LoL, [@items]; }
or non-destructive:
my $size = 2; die "Uneven list" if @list % $size; my @LoL; for my $index ( 0.. $#list ){ my $rem = $index % $size; $LoL[($index - $rem)/$size]->[$rem] = $list[$index]; }
Answer: How do I loop through a list two or more elements at a time?
contributed by petral

To be pedantic, the question was "two or more".
Here's a conventional answer which allows for varying the grouping size. (Just to make it a little interesting, I included an alternate method for dealing with the last group being short.)

my@a=qw(a b c d e f); my $grpsiz = 2; if (@a% $grpsiz) { push @a, ("") x ($grpsiz - @a % $grpsiz) } for (my$i = 0; $i <= $#a; $i += $grpsiz) { print @a[$i .. $i+$grpsiz-1] }
Answer: How do I loop through a list two or more elements at a time?
contributed by jeroenes

my %hash = @list; print "$_ - $hash{$_}\n" for keys %hash;
Answer: How do I loop through a list two or more elements at a time?
contributed by duff

In perl6 you'd just use the built-in facilities of your ordinary for loop:

for @array -> $a, $b { ... } for @array -> $one, $two, $three { ... }

Due to some regularization of the language, for loops are aware of the arity of the code block, and pulls off as many elements as needed. This also works for map as well:

my @bytwo = map -> $a, $b { [$a,$b] } @array;
Answer: How do I loop through a list two or more elements at a time?
contributed by tachyon

my @ary = qw(a b c d e f g); @_ = @ary; while (my ($one,$two) = (shift @_, shift @_)) { print "$one $two\n"; last unless defined $two; }
Answer: How do I loop through a list two or more elements at a time?
contributed by je44ery

Just now I needed a +=3 list loop, and I made a hash of anonymous arrays:

my %hash = ( 'one' => [ '1', 'first' ], 'beta' => [ '2', 'second' ], 'zeta' => [ '-1', 'last' ], ); while ((my ($key, $value)) = each %hash) { a_func_w_3_args($key, $value->[0], $value->[1]); }
The big plus for me in this format was that it makes the step 3 iteration of the data painfully obvious. Hopefully, the code isn't too painful, tho.

Please (register and) log in if you wish to add an answer



  • Posts are HTML formatted. Put <p> </p> tags around your paragraphs. Put <code> </code> tags around your code and data!
  • Read Where should I post X? if you're not absolutely sure you're posting in the right place.
  • Please read these before you post! —
  • Posts may use any of the Perl Monks Approved HTML tags:
    a, abbr, b, big, blockquote, br, caption, center, col, colgroup, dd, del, div, dl, dt, em, font, h1, h2, h3, h4, h5, h6, hr, i, ins, li, ol, p, pre, readmore, small, span, spoiler, strike, strong, sub, sup, table, tbody, td, tfoot, th, thead, tr, tt, u, ul, wbr
  • Outside of code tags, you may need to use entities for some characters:
            For:     Use:
    & &amp;
    < &lt;
    > &gt;
    [ &#91;
    ] &#93;
  • Link using PerlMonks shortcuts! What shortcuts can I use for linking?
  • See Writeup Formatting Tips and other pages linked from there for more info.
  • Log In?
    Username:
    Password:

    What's my password?
    Create A New User
    Chatterbox?
    and the web crawler heard nothing...

    How do I use this? | Other CB clients
    Other Users?
    Others browsing the Monastery: (4)
    As of 2014-09-20 17:05 GMT
    Sections?
    Information?
    Find Nodes?
    Leftovers?
      Voting Booth?

      How do you remember the number of days in each month?











      Results (160 votes), past polls