当前位置:  开发笔记 > 编程语言 > 正文

如何在Perl foreach循环中一次读取两个项目?

如何解决《如何在Perlforeach循环中一次读取两个项目?》经验,为你挑选了6个好方法。

我正在寻找的是:

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

收益:

i:1, j:2
i:3, j:4
i:5, j:6

为了回应下面的一个非常好的建议,我需要指定此脚本将在其他人的构建服务器上运行,并且我不允许使用CPAN中的任何模块.仅限标准Perl.



1> mirod..:

我认为正确的方法是使用来自List :: MoreUtils的natatime:

来自文档:

natatime BLOCK LIST

创建一个数组迭代器,用于一次循环一个$n项目块中的数组.(n一次,得到它?).一个例子可能是一个比我用文字更好的解释.

例:

 my @x = ('a' .. 'g');
 my $it = natatime 3, @x;
 while (my @vals = $it->())
 {
     print "@vals\n";
 }

这打印

a b c
d e f
g

执行List::MoreUtils::natatime:

sub natatime ($@)
{
    my $n = shift;
    my @list = @_;

    return sub
    {
        return splice @list, 0, $n;
    }
}


请注意,foreach和natatime之间略有不同.foreach更快,内存消耗更少(不会像natatime内部那样复制数组)并允许数组成员修改,例如foreach my $ a(@x){$ a ++}与$ _ ++ foreach @x相同
如果确实如此,natatime不需要复制列表:my $ list =\@_; 然后是:拼接@ $ list,0,$ n;

2> Andrew Barne..:

我会用拼接.

my @list = qw(1 2 3 4 5 6);
while(my ($i,$j) = splice(@list,0,2)) {
  print "i: $i, j: $j\n";
}



3> Jack M...:

我想你想要以不同的方式做到这一点.试试这个:

while (scalar(@list) > 0) {
    $i = shift(@list);
    $j = shift(@list);
    print "i: $i, j:$j\n";
} 

请记住,这将破坏列表,但它将适用于那个小循环.



4> Brad Gilbert..:

设置一些测试数据,然后导入say:

use Modern::Perl;
use List::AllUtils qw'zip';

my @array = zip @{['a'..'z']}, @{[1..26]} ;

使用增量变量进行简单循环.

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

循环使用.List::Pairwise  (pair)

    use List::Pairwise qw'pair';

    for my $pair (pair @array){
      my($a,$b) = @$pair;

      say "$a => $b";
    }

使用,一次循环数组2 .List::MoreUtils  (natatime)

    use List::AllUtils qw'natatime';

    my $iter = natatime 2, @array;
    while( my($a,$b) = $iter->() ){
      say "$a => $b";
    }

将其强制转换为哈希值,然后遍历键.如果你不关心订单,这很有用.

    {
      my %map = @array;
      for my $key (keys %map){
        my $value = $map{$key};
        say "$key => $value";
      }
    }



5> chaos..:

不幸的是,最接近的等同物是老派:

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

我更喜欢Jack M的答案,但是我会用更性感的Perl来写它:

while(@list) {
    my $i = shift @list;
    my $j = shift @list;
    print "i: $i, j:$j\n";
}


()循环的标准+1.一些控制结构是经典的,因为它们工作=).

6> brian d foy..:

如果我只能使用没有模块的标准Perl,我可能会下降到一个C风格的for循环,数量为2:

for( my $i = 0; $i < @array; $i += 2 ) {
    my( $i, $j ) = @array[ $i, $i+1 ];
    ...
    }

但是,如果您想从其中一个无法使用的模块中获得某些东西,您可以将该模块添加到您的代码中.如果您可以编写代码,则可以使用模块.您可能只需要在模块中包含您在@INC适当设置时提供的所有代码.这是inc :: Module :: Install和PAR的基本思想.

我花了很多时间使用构建系统来创建自己的CPAN存储库,从其私有CPAN安装其依赖项,然后测试代码.拥有构建服务器场并不排除使用模块; 这是当地的政策.然而,即使有可能,这在所有情况下都没有意义.

推荐阅读
拾味湖
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有