6

I have a simple array with names in it, and I want to be able to easily print out the number of times each name appears.

I have tried making a ton of for loops an diff statements to first make another array with unique values then, trying to count the values in the orinal array and store them in a 3rd array. This seemed overly complex, and i wanted to see if maybe there was a much simpler way to do this.

Chris Seymour
  • 83,387
  • 30
  • 160
  • 202
Ten Digit Grid
  • 1,315
  • 4
  • 22
  • 43

3 Answers3

15

Use a hash to count the number of times each name occurs:

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
        };
toolic
  • 57,801
  • 17
  • 75
  • 117
4
my %counts;
++$counts{$_} for @names;
my @unique = keys(%counts);

can be shortened to

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

The former loses the order of the names, whereas the latter has the advantage of preserving the order. (It keeps the first of duplicates.)

The latter is also an idiomatic way of getting unique members of a list. Normally, the has of counts are just a side-effect, but in this, it's a desired product. :)

ikegami
  • 367,544
  • 15
  • 269
  • 518
3

The easiest way to do this is to take advantage of hashes.

my @names = qw/joe bob sue bob mike sally mike bob sally dale joe/;
my %counts;
$counts{$_}++ for @names;

This will give you a hash that looks like:

      'dale' => 1,
      'sue' => 1,
      'joe' => 2,
      'mike' => 2,
      'bob' => 3,
      'sally' => 2
friedo
  • 65,762
  • 16
  • 114
  • 184