10

これは失敗します:

my @a = ("a", "b", "c", "d", "e");
my %h = map { "prefix-$_" => 1 } @a;

このエラーで:

Not enough arguments for map at foo.pl line 4, near "} @a"

しかし、これは機能します:

my @a = ("a", "b", "c", "d", "e");
my %h = map { "prefix-" . $_ => 1 } @a;

なぜ?

4

5 に答える 5

21

PerlはBLOCKではなくEXPR(たとえばハッシュ参照)を推測しているためです。これは機能するはずです(「+」記号に注意してください):

my @a = ("a", "b", "c", "d", "e");
my %h = map { +"prefix-$_" => 1 } @a;

http://perldoc.perl.org/functions/map.htmlを参照してください。

于 2008-11-07T00:45:51.690 に答える
13

私はそれを次のように書くことを好みます

my %h = map { ("prefix-$_" => 1) } @a;

意図を示すために、2 要素のリストを返しています。

于 2008-11-07T02:41:01.333 に答える
11

差出人perldoc -f map

           "{" starts both hash references and blocks, so "map { ..."
           could be either the start of map BLOCK LIST or map EXPR, LIST.
           Because perl doesn’t look ahead for the closing "}" it has to
           take a guess at which its dealing with based what it finds just
           after the "{". Usually it gets it right, but if it doesn’t it
           won’t realize something is wrong until it gets to the "}" and
           encounters the missing (or unexpected) comma. The syntax error
           will be reported close to the "}" but you’ll need to change
           something near the "{" such as using a unary "+" to give perl
           some help:

             %hash = map {  "\L$_", 1  } @array  # perl guesses EXPR.  wrong
             %hash = map { +"\L$_", 1  } @array  # perl guesses BLOCK. right
             %hash = map { ("\L$_", 1) } @array  # this also works
             %hash = map {  lc($_), 1  } @array  # as does this.
             %hash = map +( lc($_), 1 ), @array  # this is EXPR and works!
             %hash = map  ( lc($_), 1 ), @array  # evaluates to (1, @array)

           or to force an anon hash constructor use "+{"

             @hashes = map +{ lc($_), 1 }, @array # EXPR, so needs , at end

           and you get list of anonymous hashes each with only 1 entry.
于 2008-11-07T00:48:44.040 に答える
6

また、ハッシュを初期化する別の方法として、次のようにすることもできます。

my @a = qw( a b c d e );
my %h;
@h{@a} = ();

これにより、5 つのキーのそれぞれに対して undef エントリが作成されます。それらにすべて真の値を与えたい場合は、これを行います。

@h{@a} = (1) x @a;

ループを使用して明示的に行うこともできます。

@h{$_} = 1 for @a;
于 2008-11-07T02:42:53.373 に答える
1

と思います

map { ; "prefix-$_" => 1 } @a;

ハッシュ参照ではなくステートメントのブロックであることを指定する限り、より慣用的です。null ステートメントで開始しているだけです。

于 2008-11-07T06:24:22.693 に答える