How do I read two items at a time in a Perl foreach loop?

前端 未结 19 1426
你的背包
你的背包 2020-12-14 15:12

What I\'m looking for is something like:

@list = qw(1 2 3 4 5 6);
foreach (@list) {
  #perl magic goes here 
  print \"i: $i, j:$j\\n\";
}

相关标签:
19条回答
  • 2020-12-14 15:26

    I'd use splice.

    my @list = qw(1 2 3 4 5 6);
    while(my ($i,$j) = splice(@list,0,2)) {
      print "i: $i, j: $j\n";
    }
    
    0 讨论(0)
  • 2020-12-14 15:27
    while ($#rec>0) {
      my($a,$b) = ( shift(@rec), shift(@rec) );
      print "($a,$b)\n";
    }
    
    0 讨论(0)
  • 2020-12-14 15:28

    The closest equivalent is, unfortunately, going old-school:

    for(my $ix = 0; $ix <= $#list; $ix += 2) {
        my $i = $list[$ix];
        my $j = $list[$ix + 1];
        print "i: $i, j:$j\n";
    }
    

    I like Jack M's answer better, really, though I would write it in sexier Perl:

    while(@list) {
        my $i = shift @list;
        my $j = shift @list;
        print "i: $i, j:$j\n";
    }
    
    0 讨论(0)
  • 2020-12-14 15:31

    Using a for loop would do what you need.

    use strict;
    use warnings;
    
    my @list = qw(1 2 3 4 5 );
    my $i = 0;
    
    for ($i = 0; $i < scalar(@list); $i++)
    {
        my $a = $list[$i];
        my $b = $list[++$i];
        if(defined($a)) {
            print "a:$a";
        }
        if(defined($b)) {
            print "b:$b";
        }   
        print "\n";
    }
    

    edit: I corrected my post to use the scalar function to retrieve the size of the array and also add some checking in case the array does not contain an even number of elements.

    0 讨论(0)
  • 2020-12-14 15:32

    Set up some test data, and import say:

    use Modern::Perl;
    use List::AllUtils qw'zip';
    
    my @array = zip @{['a'..'z']}, @{[1..26]} ;
    

    Simple looping using an increment variable.

        {
          my $i = 0;
          while(
            (my($a,$b) = @array[$i++,$i++]),
            $i <= @array # boolean test
          ){
            say "$a => $b";
          }
        }
    

    Looping over pairs using List::Pairwise  (pair).

        use List::Pairwise qw'pair';
    
        for my $pair (pair @array){
          my($a,$b) = @$pair;
    
          say "$a => $b";
        }
    

    Looping over array 2 at a time, using List::MoreUtils  (natatime).

        use List::AllUtils qw'natatime';
    
        my $iter = natatime 2, @array;
        while( my($a,$b) = $iter->() ){
          say "$a => $b";
        }
    

    Coerce it into a hash, and loop over the keys. Useful if you don't care about the order.

        {
          my %map = @array;
          for my $key (keys %map){
            my $value = $map{$key};
            say "$key => $value";
          }
        }
    
    0 讨论(0)
  • 2020-12-14 15:33

    As Mirod explains, there isn't much code to it. Here's pretty much all you would need. (Note that I don't have any checks for odd-numbered lists or the like.)

    #!/usr/bin/env perl
    use strict;
    use warnings;
    
    my @list = qw/1 2 3 4 5 6/;
    my $get_em = get_by(2, @list);
    
    while ( my ($i, $j) = $get_em->() ) {
      print "i: $i, j: $j\n";
    }
    
    sub get_by {
      my $n = shift;
      my @list = @_;
    
      return sub {
        return splice @list, 0, $n;
      }
    }
    
    0 讨论(0)
提交回复
热议问题