我很难理解下面 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
这是“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;在最前面(并处理全屏消息:(。