1

使用しているコード行の数を削減しようとしていますが、かなり単純な問題が発生しています(ただし、参照に頭を悩ませ始めたばかりなので、困惑しています)。

特定の順序でいくつかの値を連結しようとしています。私のコードは次のようになります。

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;

私が得ているのは、すべてを1つの文字列にまとめるのではなく、「4」です。

私が達成しようとしているのは、より短いバージョンです...

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

(私は実際に約25をつなぎ合わせようとしています$query->params。簡潔にするために4つだけ与えました)

4

5 に答える 5

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

これはスカラー割り当てであり、マップ操作にスカラーコンテキストを提供します。 スカラーコンテキストのmapは、生成されたはずの要素の数を返します。

その特定のコード行はjoin()の使用を求めていますが、関数型プログラミングのバックグラウンドを持っている場合は、reduceの方が快適かもしれません。

use List::Util 'reduce';
$return_name = reduce { $a . $query->param($b) . $separator } "", @vals;
于 2009-10-19T17:58:20.070 に答える
4

あなたの問題の一部は、どのように機能するかについての混乱mapです。

map引数のリストを取り、リストの要素に対して操作を実行し、結果から新しいリストを作成します。スカラーコンテキストでは、新しいリストのメンバーの数を返します。

ほとんどの場合、map操作で割り当てを行う必要はありません。

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

代入が理にかなっている1つの場所は、通常はの値を変更する操作を使用する必要があるが$_、マップする引数を変更せずに保持する必要がある場合です。

その説明はひどく明確ではありません。これらの例を確認してください。私が言っていることを明確にするのに役立つはずです。最初の図は、マップが処理する値を変更できることを示しています。

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' ); 

または、次のことができます。

List :: MoreUtils qw(apply);を使用します。

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コードの2つのチャンクは、まったく同じ結果を生成します。

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

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

これがあなたにについて考える方法を学ぶのにいくらかの助けを与えたことを願っていますmapgrepそれ(およびのような関連する構造)の使用法を学んだら、apply通常のループコードを使用して構築したときに信じられないほど冗長になる可能性のあるアイデアを簡潔に表現できるようになります。

于 2009-10-19T18:04:01.493 に答える
4

map文字列ではなくリストを返します。これを試して:

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

または、本当に行数を減らしたい場合は、これを試してください:

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

(1 行のバージョンは、dsm の回答に触発されました。)

于 2009-10-19T16:00:02.647 に答える
3

これを試して:

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

「4」を取得する理由に答えるには、結果の配列のカーディナリティをスカラーに割り当てているためです。

于 2009-10-19T15:59:53.677 に答える
1

あなたが受け取ったすべての良い答えに加えて、注意してください

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

次のように書くことができます

$return_name .= $query->param($_) . $separator;
于 2009-10-19T18:03:24.147 に答える