В Perl, как я могу выполнить итерации по нескольким элементам массива?

У меня есть файл CSV, который я использую split проанализировать в массив N объекты, где N является кратным 3.

Есть ли способ, которым я могу сделать это

foreach my ( $a, $b, $c ) ( @d ) {}

подобный Python?

6
задан Sinan Ünür 8 July 2010 в 22:24
поделиться

5 ответов

Вы можете использовать List :: MoreUtils :: natatime . Из документации:

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

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;
        }
    }
}
12
ответ дан 8 December 2019 в 02:34
поделиться

Я решил эту проблему в своем модуле List :: Gen на CPAN.

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

}

Вы также можете импортировать функцию mapn , которая используется List :: Gen для реализации с помощью :

use List::Gen qw/mapn/;

mapn {

   # do something with the slices in @_

} 3 => @list;
14
ответ дан 8 December 2019 в 02:34
поделиться
@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
4
ответ дан 8 December 2019 в 02:34
поделиться

Непросто. Лучше сделать @d массивом из трехэлементных кортежей, вставив элементы в массив в качестве ссылки на массив:

foreach my $line (<>)
    push @d, [ split /,/, $line ];

(за исключением того, что вам действительно следует использовать один из CSV модули из CPAN.

1
ответ дан 8 December 2019 в 02:34
поделиться
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
4
ответ дан 8 December 2019 в 02:34
поделиться
Другие вопросы по тегам:

Похожие вопросы: