使用 map 在数组中创建出现的哈希值

create a hash of occurrences in an array with map

我似乎记得有一种“聪明”的方法可以使用 Perl map 从数组创建散列,这样键就是数组的元素,值就是数组的数量元素出现的次数。像这样的东西,虽然这不起作用:

$ perl -e '@a = ('a','a','b','c'); %h = map { $_ => $_ + 1  } @a ; foreach $k (keys (%h)) { print "$k -> $h{$k}\n"}'
c -> 1
b -> 1
a -> 2
$

我是在幻想吗?我该怎么做?

我不确定这是否是您要查找的内容,但您可以使用 for 而不是 map:

轻松地做到这一点
$ perl -e '@a = ('a','a','b','c'); $h{$_}++ for @a; foreach $k (keys (%h)) { print "$k -> $h{$k}\n"}'
c -> 1
b -> 1
a -> 2

您可以编写 map {$h{$_}++} @a 忽略它的 return 值,但为什么要这样做? for (@a){$h{$_}++} 很容易打字。

那你为什么做呢?

map 用于转换列表。它接受一个输入列表并生成一个输出列表。如果您以不同的方式使用副作用而不是输出,它可能会混淆 reader。

此外,虽然 map 被优化为在 void 上下文中调用时不创建输出列表,但速度较慢:

use warnings;
use strict;
use Benchmark qw/cmpthese/;
my @in = map {chr(int(rand(127)+1))} 1..10000;

my %out;
cmpthese(10000,
         {stmtfor => sub{%out = (); $out{$_}++ for @in},
          voidmap => sub{%out = (); map {$out{$_}++} @in;},
          }
     );

__END__

          Rate voidmap stmtfor
voidmap 2075/s      --    -17%
stmtfor 2513/s     21%      --