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

在Perl中,如何迭代数组的多个元素?,perl,Perl,我有一个CSV文件,我使用split将其解析为N项的数组,其中N是3的倍数 我有办法做到这一点吗 foreach my ( $a, $b, $c ) ( @d ) {} 类似于Python @z=(1,2,3,4,5,6,7,8,9,0); for( @tuple=splice(@z,0,3); @tuple; @tuple=splice(@z,0,3) ) { print "$tuple[0] $tuple[1] $tuple[2]\n"; } 产生: 1 2 3 4 5 6

我有一个CSV文件,我使用
split
将其解析为
N
项的数组,其中
N
3
的倍数

我有办法做到这一点吗

foreach my ( $a, $b, $c ) ( @d ) {}
类似于Python

@z=(1,2,3,4,5,6,7,8,9,0);

for( @tuple=splice(@z,0,3); @tuple; @tuple=splice(@z,0,3) ) 
{ 
  print "$tuple[0] $tuple[1] $tuple[2]\n"; 
}
产生:

1 2 3
4 5 6
7 8 9
0

不容易。您最好将
@d
作为三个元素元组的数组,将元素推到数组上作为数组引用:

foreach my $line (<>)
    push @d, [ split /,/, $line ];
foreach my$行()
推送@d,[split/,/,$line];
(除了您确实应该使用CPAN的CSV模块之一。

您可以使用。从文档:

my @x = ('a' .. 'g');
my $it = natatime 3, @x;
while (my @vals = $it->()) {
    print "@vals\n";
}
natatime
是在XS中实现的,因此为了提高效率,您应该更喜欢它

#!/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;
        }
    }
}
!/usr/bin/perl
使用严格;使用警告;
我的@v=('a'..'z');
我的$it=make3it(\@v);
而(my@tuple=$it->()){
打印“@tuple\n”;
}
sub make_3it{
我的($arr)=@;
{
我的$lower=0;
返回接头{
返回,除非$lower<@$arr;
my$upper=$lower+2;
@$arr>$upper或$upper=$#$arr;
我的@ret=@$arr[$lower..$upper];
$lower=$lower+1;
返回@ret;
}
}
}

我在关于CPAN的模块中解决了这个问题

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

use List::Gen qw/mapn/;

mapn {

   # do something with the slices in @_

} 3 => @list;
这将产生:

one two three
four five six
seven eight nine

thx,这是一个快速的内部破解,没想到会这么难。不要使用
$a
$b
作为变量名。它们是专门打包的作用域变量,用于
排序
。如果你能做到这一点,那就太酷了。如果你在排序之外,那没关系。但是如果它是一个单行程序,你可能会重复使用请不要“用手”解析CSV文件——使用,它会处理所有令人讨厌的边缘小案例,这些小案例最终会从背后咬到你。@eruciform=>如果你用
my
$a
$b
进行词汇化,那么危险就在于,然后在同一范围内调用
sort
sort
会爆炸,抱怨它不能一次定位一个词汇变量-我喜欢:-)嘿,很有趣,我不知道这个。可能是接头周围的单线闭合。:-)@eruciform:在逻辑上,是的,但是List::Util和List::MoreUtils中的函数是用XS编写的,以获得最大的速度。当解析大量数据时,使用您需要的确切函数而不是使用内置函数确实是有好处的。@erCIFORM:实际上,不是。
List::MoreUtils
中的函数是用XS(即C)实现的,以提供尽可能高的效率。使用
splice
会引入大量内存开销和移动指针等,如果N足够大,人们可能会注意到这些开销。@erucform:XS模块不是。但是,List::MoreUtils的纯perl版本与您描述的完全一样:围绕列表副本的闭包,带有一个拼接。:)它们是否真的被化名为“我的”呢?或者只是在一个“for”循环中?“我的”应该复制一份。“by”是否绕过了这个问题?Perl foreach循环中的
my
变量永远不是副本,而是别名。一个词汇范围的别名,但一个别名。我能说的是非常好!只是重申思南的评论。这个模块看起来很有趣。很好的工作。这会破坏
@z
数组,暂时编写可能更好loop@eric:是的。这是一个快速的解决方案。
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";
}
one two three
four five six
seven eight nine