请向我解释地图在这种情况下是如何工作的



split之后,我得到一个值为1 2 4 8 16 32 64@digits数组。然而,我无法理解它在块if ($digits [-1] == 4) {}中的处理机制。之后,只有4 6 4值保留在同一数组中。是的,我看到这段代码工作正常,但如何在不处理it的情况下从数组中删除不必要的值?

my @input_numbers = qw(1 2 4 8 16 32 64);
my @result = map {
my @digits = split //, $_;
if ($digits[-1] == 4) {
@digits;
} else {
(  );
}
} @input_numbers;
print join(" ", @result); # 4 6 4

映射的工作方式是一次获取其输入列表中的一个元素,在$_中使用该元素在块中运行代码,并返回上一个求值语句(返回(所做的一切。在处理了输入列表的所有元素之后,这些返回值构成了它的输出列表。

因此,块中的@digits在每次迭代时都被分配(带有(当前处理的元素的数字,而不是所有元素的所有数字然后它们要么在列表中返回,要么返回空列表,从而";消失";在整个返回列表中

由于当最后一个是4时,您会从块中返回带有这些数字的列表,因此当map块处理4(数组中的第三个元素(时,它会返回4,而当它处理64时,它将返回带有数字64的列表。共CCD_ 15。


这也可能有助于实现map { ... } LIST语法中的块代表子程序调用,其中为每个元素执行这样的代码。这是通过使用原型提供的。请注意,建议不要随意使用原型是正确的,但这里需要它们。

这不能在纯Perl中完全实现,但这里有一个简单的示例

sub a_bit_like_map :prototype(&$) {
my ($code, @in) = @_;
my @res;
foreach my $el (@in) {
local $_ = $el;
push @res, $code->($el);
}
return @res
}

现在这可以称为

my @mapped = a_bit_like_map( sub { ... }, LIST );
my @mapped = a_bit_like_map { ... } LIST;

这个:prototype属性在较新的Perls中是必要的,并且其中启用了签名,因为如果没有它,语法将与签名的语法冲突。

对于较旧的Perl,您会看到它们被用作sub func(&@) { ... }


使用map作为滤波器的方法,也是

这里有两件事。map在列表上下文中评估其代码。

其次,块返回其最后一个求值表达式。

map中,最后一个求值的表达式来自ifelse块,因为该结构之后没有其他语句。如果是if的情况,则返回@digits,它会将一个或多个新项添加到map的输出列表中。

else的情况下,最后计算的表达式是( ),它是空列表。这没有向输出列表添加新元素;不包括";来自该特定输入元素的结果。

我可能会把这个任务写成一个列表管道。grep选择我们知道要处理的元素,然后map处理它得到的一切:

my @result = map { split // } grep { /4z/ } @input_numbers;

最新更新