关于 Perl 映射函数的建议

Posted

技术标签:

【中文标题】关于 Perl 映射函数的建议【英文标题】:Advice on Perl map function 【发布时间】:2021-07-22 14:02:45 【问题描述】:

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

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

@res 的值为AAAC。我原以为它只是AC,因为@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; 
    ;

J

【问题讨论】:

始终使用use strict; use warnings; 或同等名称。它会揭示你为什么得到AAAC 【参考方案1】:

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

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

做你想做的事:

my @res = map  $list[ $_ ]  grep  defined  @curr;

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

my @res = map  defined $_ ? $list[$_] : ()  @curr;

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

注意 使用use warnings;,您会听到所有相关信息

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

(它会将其转换为数字)

每个脚本确实必须use warnings;(和use strict;)开头。有时,继承旧脚本的最重要部分是立即将use warnings; 粘贴在顶部(并通过全屏消息工作:(。

【讨论】:

【参考方案2】:

我想回答我自己的问题,undef 有时被视为零。这就是为什么 $list[undef] 与 $list[0]

相同的原因

【讨论】:

undef 是一个有效的标量,一个在数值操作/上下文中为 undef 的变量,它假装为 0,而在字符串操作/上下文中,它假装为空字符串。正如@zdim 提到的如果启用警告,程序将警告消息 更简单地说,当您将 undef 视为数字时,您会收到警告(如果启用)并且使用 0(而不是杀死您的程序)。

以上是关于关于 Perl 映射函数的建议的主要内容,如果未能解决你的问题,请参考以下文章

关于如何从域 (ORM) 对象映射到数据传输对象 (DTO) 的建议

为啥我的 Perl 映射不返回任何内容?

熊猫列内的映射值

在 perl 中使用嵌套映射是一种好习惯吗?

手动映射 JSON 对象时,RestKit 关系未映射

Lakka系统的游戏手柄映射方法(转自 家麟)