名前が含まれる単純な配列があり、各名前が表示される回数を簡単に印刷できるようにしたいと考えています。
大量のforループをdiffステートメントにして、最初に一意の値を持つ別の配列を作成し、次に元の配列の値をカウントして3番目の配列に格納しようとしました。これは非常に複雑に思えたので、これを行うためのもっと簡単な方法があるかどうかを確認したかったのです。
ハッシュを使用して、各名前が出現する回数をカウントします。
use warnings;
use strict;
use Data::Dumper;
$Data::Dumper::Sortkeys=1;
my @names = qw(bob mike joe bob);
my %counts;
$counts{$_}++ for @names;
print Dumper(\%counts);
__END__
$VAR1 = {
'bob' => 2,
'joe' => 1,
'mike' => 1
};
my %counts;
++$counts{$_} for @names;
my @unique = keys(%counts);
に短縮することができます
my %counts;
my @unique = grep !$counts{$_}++, @names;
前者は名前の順序を失いますが、後者には順序を保持するという利点があります。(最初の重複を保持します。)
後者は、リストの一意のメンバーを取得する慣用的な方法でもあります。通常、カウントの数は単なる副作用ですが、これでは、それは望ましい製品です。:)
これを行う最も簡単な方法は、ハッシュを利用することです。
my @names = qw/joe bob sue bob mike sally mike bob sally dale joe/;
my %counts;
$counts{$_}++ for @names;
これにより、次のようなハッシュが得られます。
'dale' => 1,
'sue' => 1,
'joe' => 2,
'mike' => 2,
'bob' => 3,
'sally' => 2