在Perl中,如何迭代数组的多个元素?

Tim*_*mmy 6 perl

我有一个CSV文件,我用它split来解析一个N项目数组,其中N是一个倍数3.

有没有办法可以做到这一点

foreach my ( $a, $b, $c ) ( @d ) {}
Run Code Online (Sandbox Code Playgroud)

类似于Python?

Eri*_*rom 14

我在CPAN 模块List :: Gen中解决了这个问题.

use List::Gen qw/by/;

for my $items (by 3 => @list) {

    # do something with @$items which will contain 3 element slices of @list

    # unlike natatime or other common solutions, the elements in @$items are
    # aliased to @list, just like in a normal foreach loop

}
Run Code Online (Sandbox Code Playgroud)

您还可以导入该mapn函数,该函数用于List::Gen实现by:

use List::Gen qw/mapn/;

mapn {

   # do something with the slices in @_

} 3 => @list;
Run Code Online (Sandbox Code Playgroud)

  • 我只能说*非常好!* (3认同)
  • Perl foreach循环中的`my`变量永远不是副本,它始终是别名.一个词法范围的别名,但别名是别名. (2认同)

Sin*_*nür 12

您可以使用List :: MoreUtils :: natatime.来自文档:

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

natatime在XS中实现,因此您应该更喜欢它以提高效率.仅用于说明目的,以下是如何在Perl中实现三元素迭代器生成器:

#!/usr/bin/perl

use strict; use warnings;

my @v = ('a' .. 'z' );

my $it = make_3it(\@v);

while ( my @tuple = $it->() ) {
    print "@tuple\n";
}

sub make_3it {
    my ($arr) = @_;
    {
        my $lower = 0;
        return sub {
            return unless $lower < @$arr;
            my $upper = $lower + 2;
            @$arr > $upper or $upper = $#$arr;
            my @ret = @$arr[$lower .. $upper];
            $lower = $upper + 1;
            return @ret;
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

  • @eruciform:在逻辑上,是的,但是 List::Util 和 List::MoreUtils 中的函数是用 XS 编写的以获得最大速度。在解析大量数据时,使用您需要的确切函数而不是使用内置函数确实是值得的。 (2认同)
  • @eruciform:实际上,没有.`List :: MoreUtils`中的函数在XS(即C)中实现,以提供最大可能的效率.使用`splice`会引入大量的内存开销和移动指针等,如果*N*足够大,人们可能会注意到这一点. (2认同)
  • @eruciform:XS 模块不是。然而,List::MoreUtils 的纯 perl 版本与您所描述的完全一样:一个围绕列表副本的闭包,带有拼接。:) (2认同)

dal*_*ton 5

my @list = (qw(one two three four five six seven eight nine));

while (my ($m, $n, $o) = splice (@list,0,3)) {
  print "$m $n $o\n";
}
Run Code Online (Sandbox Code Playgroud)

这输出:

one two three
four five six
seven eight nine
Run Code Online (Sandbox Code Playgroud)