Perl 为什么这张地图只返回一个数字?

Perl 为什么这张地图只返回一个数字?,perl,arrays,string-concatenation,Perl,Arrays,String Concatenation,我试图减少我正在使用的代码行的数量,但最终遇到了一个相当简单的问题(尽管这让我很困惑,因为我刚刚开始对引用进行思考) 我试图按特定顺序连接多个值。。我的代码如下所示 my $separator = ":"; my @vals = qw(name last-name first-name phone); my $return_name; $return_name = map { $return_name = $return_name . $query->param($_) . $s

我试图减少我正在使用的代码行的数量,但最终遇到了一个相当简单的问题(尽管这让我很困惑,因为我刚刚开始对引用进行思考)

我试图按特定顺序连接多个值。。我的代码如下所示

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”,而不是把所有的东西缩成一根线

我试图实现的是一个简短版本的

$return_name = $query->param('name') . 
    $separator . $query->param('last-name') . 
    $separator . $query->param('first_name') . 
    $separator . $query->param('phone');
(实际上,我正在尝试将大约25个
$query->params
串在一起。为了简洁起见,我只给出了四个)

试试这个:

join $separator, 
     map { $query->param($_) } 
     ("name", "last-name", "first-name", "phone");
$return_name = join $separator, map { $query->param($_) } @vals;
要回答得到“4”的原因,这是因为要将结果数组的基数指定给标量。

请尝试以下操作:

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

要回答得到“4”的原因,这是因为将结果数组的基数指定给标量。

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

$return_name = join $separator, map { $query->param($_) } @vals;
或者,如果确实要减少行数,请尝试以下方法:

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

(单行版本的灵感来自dsm的答案。)

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

$return_name = join $separator, map { $query->param($_) } @vals;
或者,如果确实要减少行数,请尝试以下方法:

my $return_name = join ':', 
    map { $query->param($_) } 
    qw(name last-name first-name phone);
(单线版本的灵感来自dsm的答案。)

这是一个标量赋值,它为映射操作提供标量上下文。 在标量上下文中,返回将生成的元素的计数

虽然这一行代码迫切需要使用,但如果您有函数式编程背景,您可能会对reduce更熟悉:

use List::Util 'reduce';
$return_name = reduce { $a . $query->param($b) . $separator } "", @vals;
这是一个标量赋值,它为映射操作提供标量上下文。 在标量上下文中,返回将生成的元素的计数

虽然这一行代码迫切需要使用,但如果您有函数式编程背景,您可能会对reduce更熟悉:

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

除了你收到的所有好答案之外,请注意

$return_name = $return_name . $query->param($_) . $separator;
可以写成

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

除了你收到的所有好答案之外,请注意

$return_name = $return_name . $query->param($_) . $separator;
可以写成

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

部分问题在于对
map
的工作原理感到困惑

map
获取参数列表,对列表中的元素执行操作,并根据结果创建新列表。在标量上下文中,它返回新列表中的成员数

在大多数情况下,您不希望在
map
操作中执行赋值

# no assignment needed to set @foo
my @foo = map $_+2, 1,2,3; 
# @foo = (3,4,5);
赋值有意义的一个地方是,如果您需要使用一个通常会更改
$\uu
值的操作,但您需要保持映射的参数不变

这一解释并不十分清楚。看看这些例子,它们应该有助于澄清我所说的。第一个示例显示映射可以更改其处理的值:

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' ); 
或者你可以:

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(适用)

最基本的
map
就像
for
循环的一种特殊形式。这两段代码产生完全相同的结果:

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

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

我希望这对您学习如何思考
map
有所帮助。一旦您学会了使用它(以及相关的构造,如
grep
apply
),您将能够简洁地表达一些想法,这些想法在使用普通循环代码构建时可能会令人难以置信地冗长。

您的部分问题在于对
map
如何工作的困惑

map
获取参数列表,对列表中的元素执行操作,并根据结果创建新列表。在标量上下文中,它返回新列表中的成员数

在大多数情况下,您不希望在
map
操作中执行赋值

# no assignment needed to set @foo
my @foo = map $_+2, 1,2,3; 
# @foo = (3,4,5);
赋值有意义的一个地方是,如果您需要使用一个通常会更改
$\uu
值的操作,但您需要保持映射的参数不变

这一解释并不十分清楚。看看这些例子,它们应该有助于澄清我所说的。第一个示例显示映射可以更改其处理的值:

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' ); 
或者你可以:

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(适用)

最基本的
map
就像
for
循环的一种特殊形式。这两段代码产生完全相同的结果:

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

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

我希望这对您学习如何思考
map
有所帮助。一旦您学会了使用它(以及相关的构造,如
grep
apply
),您将能够简洁地表达想法,这些想法在使用普通循环代码构建时可能会令人难以置信地冗长。

我相信dsm的上述方法也能奏效。jbourque它像冠军一样工作!谢谢我相信dsm的上述方法也能奏效。jbourque它像冠军一样工作!谢谢道蟾蜍,这是我能得到的最好的答案。我的意思是,每个人都帮了我很大的忙,但是你的回答确实帮助我理解了它。道蟾蜍,这是我能得到的最好的答案。我的意思是,每个人都帮了我很大的忙,但你的回答确实帮助我理解了这一点。