perl: подсчитывать уникальные элементы в массиве

У меня есть простой массив с именами в нем, и я хочу иметь возможность легко распечатать, сколько раз появляется каждое имя.

Я попытался сделать массу циклов for и операторов diff, чтобы сначала создать другой массив с уникальными значениями, а затем попытаться подсчитать значения в исходном массиве и сохранить их в третьем массиве. Это казалось слишком сложным, и я хотел посмотреть, может быть, есть более простой способ сделать это.


person searayman    schedule 17.04.2012    source источник


Ответы (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
        };
person toolic    schedule 17.04.2012

my %counts;
++$counts{$_} for @names;
my @unique = keys(%counts);

можно сократить до

my %counts;
my @unique = grep !$counts{$_}++, @names;

Первый теряет порядок имен, тогда как второй имеет преимущество сохранения порядка. (Он сохраняет первый из дубликатов.)

Последний также является идиоматическим способом получения уникальных членов списка. Как правило, это всего лишь побочный эффект, но в данном случае это желанный продукт. :)

person ikegami    schedule 17.04.2012
comment
спасибо, в моей ситуации порядок не имеет большого значения, но мне это может понадобиться в будущем - person searayman; 17.04.2012

Самый простой способ сделать это — использовать хэши.

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
person friedo    schedule 17.04.2012