我试图削减对我使用的代码行数,但我有一个非常简单的问题,结束了(尽管它绊倒了我,因为我刚开始来包装我的身边引用头)

我想在一个特定的顺序连接几个值。我的代码看起来像这样..

my $separator = ":";
my @vals = qw(name last-name first-name phone);
my $return_name;
$return_name = map { 
    $return_name = $return_name . $query->param($_) . $separator 
} @vals;

我所得到的是“4”,而不是concantenating所有成一个字符串。

我所试图实现的是...

的短版
$return_name = $query->param('name') . 
    $separator . $query->param('last-name') . 
    $separator . $query->param('first_name') . 
    $separator . $query->param('phone');

(实际上,我想串起来约25 $query->params。我只给了四为简洁起见)

有帮助吗?

解决方案

你的问题的部分原因是混淆map如何工作的。

map需要的参数的列表,执行对列表的元素的操作,并创建从结果的新列表。在标量环境将返回成员在新的列表中的号码。

在大多数情况下,你不想做的map操作的任务。

# no assignment needed to set @foo
my @foo = map $_+2, 1,2,3; 
# @foo = (3,4,5);

在一个地方的分配是有道理的是,如果你需要使用通常会改变$_的值的操作,但你需要保存的参数映射不变。

这说明并不十分清楚。看看这些例子,它们应该有助于澄清我的意思。所述第一显示您映射可以改变它处理的值:

my @foo = qw( fee fie foe fum );
my @bar = map { s/e/-/g } @foo;
# @foo = ( 'f--', 'fi-', 'fo-', 'fum' ); 
# @bar = ( 2, 1, 1, '' );

要避免改变@foo你可以这样做:

my @foo = qw( fee fie foe fum );
my @bar = map { my $val = $_; $val =~ s/e/-/g } @foo;
# @foo = ( 'fee', 'fie', 'foe', 'fum' ); 
# @bar = ( 'f--', 'fi-', 'fo-', 'fum' ); 

或者你可以这样做:

使用一览:: MoreUtils QW(申请);

my @foo = qw( fee fie foe fum );
my @bar = apply { s/e/-/g } @foo;
# @foo = ( 'fee', 'fie', 'foe', 'fum' ); 
# @bar = ( 'f--', 'fi-', 'fo-', 'fum' );

在其最基本的map作品像for循环的一种特殊形式。的代码在两个组块产生完全相同的结果:

my @foo = map {$_ * 2} 1..5;

my @bar;
for (1..5) {
     my $val = $_ * 2;
     push @bar, $val;
}

我希望这个给你一些帮助学习如何思考map。一旦你学会如何使用它(以及相关的结构,如grepapply),你将能够简洁地表达,可以令人难以置信的详细使用正常的循环代码时,内置的想法。

其他提示

$return_name = map { $return_name = $return_name . $query->param($_) . $separator } @vals;

这是一个标量分配,这给地图操作标量上下文。 地图在标量上下文返回本来会生产的元件的计数。

虽然该代码特定的行十分需要使用加入() ,如果你来从功能编程背景,你可能会更舒适的降低:

use List::Util 'reduce';
$return_name = reduce { $a . $query->param($b) . $separator } "", @vals;

map返回一个列表,而不是字符串。尝试这样:

$return_name = join $separator, map { $query->param($_) } @vals;

或者,如果你真的想剪线的数量,试试这个:

my $return_name = join ':', 
    map { $query->param($_) } 
    qw(name last-name first-name phone);

(单线版本是由DSM的回答的启发。)

尝试这种情况:

join $separator, 
     map { $query->param($_) } 
     ("name", "last-name", "first-name", "phone");

要回答您得到“4”的原因,这是因为要分配所得的阵列基数为标量。

除了所有你已经收到了很好的答案,注意

$return_name = $return_name . $query->param($_) . $separator;

可以写为

$return_name .= $query->param($_) . $separator;
许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top