Perl 映射函数的建议

Joh*_*n D 3 perl dictionary

我很难理解下面 Perl 脚本中 map 函数的行为

my @list = qw/A C T G/;
my @curr = (0, undef, undef, 1);
my @res = map { $list[ $_ ] } @curr;
print @res; #prints AAAC
Run Code Online (Sandbox Code Playgroud)

值@resIS AAAC。我原以为它AC就像 的 2 个中间值@curr一样undef。

我对 map 的理解是,列表中的每一项都变成了 的值$_。所以我可以理解如何$list[0]返回 A 以及如何$list[1]返回 C。我无法理解这些undef值为什么/如何返回 A?在我看来$list[undef]不会是一个值?

我可能在这里遗漏了一些明显的东西,但非常感谢您的帮助

我从中获取此代码的脚本如下。我正在调试器中逐步完成它,我可以在返回的最后一行中看到这种行为sub gen_permutate

my @DNA = qw/A C T G/;
my $seq = gen_permutate(14, @DNA);

while ( my $strand = $seq->() ) {
print "$strand\n";

}

sub gen_permutate {
    my ($max, @list) = @_;
    my @curr;
    
    return sub {
        if ( (join '', map { $list[ $_ ] } @curr) eq $list[ -1 ] x @curr ) {
            @curr = (0) x (@curr + 1);
        else {
            my $pos = @curr; 
            while ( --$pos > -1 ) {
                ++$curr[ $pos ], last if $curr[ $pos ] < $#list; 
                $curr[ $pos ] = 0;
            }
        }
        return undef if @curr > $max;
        return join '', map { $list[ $_ ] } @curr; 
    };
}
Run Code Online (Sandbox Code Playgroud)

J

zdi*_*dim 5

这是“DWIM”的一部分——数组索引需要是一个数字,所以传入的内容被转换为一个,尽可能解释器可以做/猜测。在undef至少很清楚的情况下- 成为0.

但这确实是一个编程错误,或者至少是草率。

做你所期望的:

my @res = map { $list[ $_ ] } grep { defined } @curr;
Run Code Online (Sandbox Code Playgroud)

或者,在对列表的一次迭代中

my @res = map { defined $_ ? $list[$_] : () } @curr;
Run Code Online (Sandbox Code Playgroud)

此处由 指示的空列表()被压平到返回列表中,从而消失;所以我们也过滤内部map。但是三元组的重点是能够放置一些有意义的东西,如果一些输入需要被删除,那么grep首先有一个明确的更清晰。

注:   由于use warnings;在地方,你会听到有关它的一切

在数组元素中使用未初始化的值 $_...

(它会将其转换为数字)

每个脚本确实必须以use warnings;(和use strict;)开头。有时,继承旧脚本的最大部分是立即坚持use warnings;在最前面(并处理全屏消息:(。