Perl 相当于 Python 的枚举是什么?



我正在Perl5中寻找一个与Python的enumerate内置功能类似的函数。它将返回对数组的引用列表,其中每个数组都是[$index, $element]:

@a = ("a", "b", "c");
@b = enumerate @a;
# @b = ([0, "a"], [1, "b"], [2, "c"])

List::Util和List::MoreUtil似乎没有这个功能。还有其他模块可以吗?

您可以使用map,就像这个

my @data = qw / a b c /;
my @enumeration = map [ $_, $data[$_] ], 0 .. $#data;

enumerate返回一个迭代器,而不是列表,所以您实际上应该要求迭代器。


在Perl5.12.0及更高版本中,可以使用each迭代数组:

use strict;
use warnings 'all';
use 5.012;
my @a = qw(foo bar baz);
while (my ($i, $v) = each @a) {
    say "$i -> $v";
}
__END__
0 -> foo
1 -> bar
2 -> baz

但是,在使用each时应该非常小心;有些人甚至完全不鼓励使用它。

Perl没有内置的函数来实现这一点,但它很容易实现您自己的功能。

使用map:

my @a = qw(a b c);
my $i = 0;
my @b = map [$i++, $_], @a; # ([0, 'a'], [1, 'b'], [2, 'c'])

从v5.20开始,Perl的新slice语法做了类似的事情:

my @a = qw(a b c);
my @b = %a[0..$#a]; # (0, 'a', 1, 'b', 2, 'c')

该slice语法返回一个索引/值对列表,但它是一个平面列表。这些对没有分组到嵌套数组中。如果这对你的应用程序很重要,你可以使用List::Util中的pairmap函数来完成它:

use List::Util qw(pairmap);
my @a = qw(a b c);
my @b = pairmap {[$a, $b]} %a[0..$#a]; # ([0, 'a'], [1, 'b'], [2, 'c'])

使用List::Enumerate模块。

use List::Enumerate qw(enumerate);
@a = ("a", "b", "c");
@b = map { [ $_->index, $_->item ] } enumerate(@a);
sub enumerate(&@) {
    local *f = shift;
    my @array = @_;
    my @ret;
    my $pkg = caller;
    for ( my $i = 0 ; $i < @array ; $i++ ) {
        no strict 'refs';
        local *{ $pkg . '::a' } = $i;
        local *{ $pkg . '::b' } = $array[$i];
        push @ret, f( $i, $array[$i] );
    }
    @ret;
}
my @tmp = enumerate { ($a, $b) } 'a'..'z';
say "@tmp";

最新更新