fundflow has asked for the wisdom of the Perl Monks concerning the following question:

What is the Perl way of counting the number of occurances of elements in an array?

I.e., is there a better way than this:
@a=('a', 'b', 'a', 'a'); foreach ( @a ) { $c{$_}++; } foreach ( keys %c ) { print "$_ occurs $c{$_}\n";

Replies are listed 'Best First'.
Re: Counting occurances
by ZZamboni (Curate) on Jul 13, 2000 at 19:10 UTC
    Looks fine to me. As le mentioned, you could shorten it by rearranging like this:
    $c{$_}++ for @a;
    But it's essentially the same thing.

    --ZZamboni

RE: Counting occurances
by dempa (Friar) on Jul 13, 2000 at 17:12 UTC
    I've been thinking 'bout this for a while now, and I cannot come up with anything better. I'm sure someone else can tho'. Anyway, if you just wanted to know the number of occuranes for one element, you could use:
    @a=('a', 'b', 'a', 'a'); print "a occurs " . scalar grep(/a/,@a) . " times\n";

      Don't use a regex if you don't really want a regex, which you don't, because you now found all the items that contain "a", not just be equal to them. You probably wanted this instead:
      print "a occurs ".grep($_ eq "a", @list)," times\n";

      -- Randal L. Schwartz, Perl hacker

        OK, my point was to show that grep returned the number of occurances in scalar context, but ofcourse you're right. Point taken.

Re: Counting occurances
by le (Friar) on Jul 13, 2000 at 17:04 UTC
    Your code is doing fine. Of course, you could shorten it a little bit by saying for instead of foreach.
Re: Counting occurances
by LeGo (Chaplain) on Jul 20, 2001 at 04:20 UTC
    Another way might be to...
    %hash = map {$_=>$c{$_}++} @a; foreach (keys %d) {print "$_ occurs $c{$+}\n"};
    not possibly better but another way...
    LeGo