变量未在申请中更新

时间:2014-03-19 20:27:14

标签: perl

从Perldoc引用以在List :: AllUtils中应用

  

将BLOCK应用于LIST中的每个项目,并在应用BLOCK后返回值列表。在标量上下文中,返回最后一个元素。此函数类似于“map”,但不会修改输入列表的元素。

我想检查号码是否是阿姆斯壮号码。由于标量上下文中的map返回元素的数量,因此apply返回最后一个元素$sum。我使用了以下

#!/usr/bin/perl

use List::AllUtils qw(apply sum);
use v5.10;
use strict;
use warnings;

say "Enter the input : ";
my $input_number = <STDIN>;
chomp($input_number);
my $sum;
my $out = apply { $sum += $_ ** 3 } split //, $input_number ;
say $out;

我希望$sum返回$out。但我得到$input_number的最后一个字符。

输出:

Enter the input : 
153
3

编辑:

我有阿姆斯特朗号的解决方案。我需要知道apply为什么不返回$sum并返回$input_number的最后一个字符。

3 个答案:

答案 0 :(得分:3)

您不需要应用或映射,只需要for循环:

my $input_number = 153;
my $sum = 0;
$sum += $_ ** 3 for split //, $input_number ;

print ($sum == $input_number) ? "Yep, it's an armstrong num\n" : "nope\n";

如果你想拉出最后一个元素,你可以这样做:

my $out = (map {$sum += $_ ** 3} split //, $input_number)[-1];

要显示apply实际上做了什么,可以查看来源:

sub apply (&@) {
    my $action = shift;
    &$action foreach my @values = @_;
    wantarray ? @values : $values[-1];
}

这将生成原始数组的副本,然后在每个元素上运行代码块。但请注意,您必须实际更改$_或apply的值才会返回原始元素。

我认为apply专门用于将正则表达式应用于数组而不破坏原始数组的情况。例如,以下内容是等效的:

my @newarray = apply {s/\n//g} @oldarray;
my @newarray = map {my $text = $_; $text =~ s/\n//g; $text} @oldarray;

最终,以您对代码的期望方式申请工作的唯一方法是执行以下操作:

my $out = apply { $_ = $sum += $_ ** 3 } split //, $input_number ;

答案 1 :(得分:1)

来自documentation

  

应用BLOCK LIST

     

将BLOCK应用于LIST中的每个项目,并在应用BLOCK后返回值列表。 在标量上下文中,返回最后一个元素。

更清楚地说明文档:apply获取一个列表,对其应用BLOCK,然后返回

  • (可能已修改)列表(列表上下文)
  • (可能已修改)列表的最后一个元素(标量上下文)

您还没有真正修改过列表,您只更改了$sum变量,因此您获得的结果是您传入的列表的最后一个元素。

改为使用reduce功能:

use List::Util qw(reduce);

my $sum = reduce { $a + ($b ** 3) } 1 .. 10;
# 3025

答案 2 :(得分:1)

你误解了文档的含义是“BLOCK被应用后的值列表”。它在每次BLOCK应用后返回$_的值,而不是BLOCK本身的返回值。与map不同,$_初始化为元素的副本。