为什么这个地图返回一个数字?
-
22-09-2019 - |
题
我试图削减对我使用的代码行数,但我有一个非常简单的问题,结束了(尽管它绊倒了我,因为我刚开始来包装我的身边引用头)
我想在一个特定的顺序连接几个值。我的代码看起来像这样..
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
。一旦你学会如何使用它(以及相关的结构,如grep
和apply
),你将能够简洁地表达,可以令人难以置信的详细使用正常的循环代码时,内置的想法。
其他提示
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;
不隶属于 StackOverflow