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

Hi.

I got an array with different values (some which are repeated). I need a way of picking out the one that is repeated most times in this array.

Does anyone know a simple and fast way of doing this?

Thanks,
Ralph.

Replies are listed 'Best First'.
Re: finding the most popular in array
by Anonymous Monk on Sep 10, 2001 at 02:43 UTC
    $hash{$_}++ foreach @array; foreach keys %hash { $max = $_ if $hash{$_} > $hash{$max} }; print $max, "\n";
      I liked your way of doing it, since it's two passes and the original question only wanted the most popular. Much better than sorting.

      The other day I caught myself coding this same thing (boiling down a larger problem) but with this variation:

      $hash{$_}++ for @array; %hash=reverse %hash; for (keys %hash) { $max = $_ > $max ? $_ : $max }; print $hash{$max}, "\n";
      Thank goodness for TIMTOWDI.
        It could be done in one loop too.
        @a= qw(a b c d e c d e c d e c d e c d e a b c d a b c d a b c d a b c + d a b a b a e e d a a a a a a a a); for(@a) { if ($c<$r{$_}++) { $m=$_; $c=$r{$_} } }
        And this is to check.
        for (keys %r){print "$_ $r{$_}\n"}; print "\n\$m is $m\n\$c is $c";
        Hopes
        I hope you had enjoyed it
Re: finding the most popular in array
by suaveant (Parson) on Sep 10, 2001 at 02:43 UTC
    my %pop; my @poporder; for(@ary) { $pop{$_}++; } for(sort { $pop{$a} <=> $pop{$b} } keys %pop) { print "$_: $pop{$_}\n"; } # can also do @poporder = sort { $pop{$a} <=> $pop{$b} } keys %pop;
    this goes through your array, ++ing the hash element with the key as the array item. It then sorts your hash by the values of those keys and prints them out, or as the last line show, assigns them to a new array in order. (replace @ary with your array name)

                    - Ant
                    - Some of my best work - Fish Dinner

Re: finding the most popular in array
by tachyon (Chancellor) on Sep 10, 2001 at 02:51 UTC

    Yes you use a hash to count the occurences, sort on the values of this and print it.

    my @ary = qw ( a a a a a b b b c c c c c c d d d d ); # use a hash to count occurrences my %pop; $pop{$_}++ for @ary; # sort hash on values, store sorted keys in array my @pop_sort = sort { $pop{$b} <=> $pop{$a} } keys %pop; # now print most popular print "Most popular $pop_sort[0]\n"; print "Least popular $pop_sort[-1]\n"; # show hash print "Key Count\n"; for my $key (@pop_sort) { print "$key => $pop{$key}\n"; }

    cheers

    tachyon

    s&&rsenoyhcatreve&&&s&n.+t&"$'$`$\"$\&"&ee&&y&srve&&d&&print

Re: finding the most popular in array
by Jazz (Curate) on Sep 10, 2001 at 08:58 UTC
    If all you want is a quick and dirty way of showing the most repeated element, try this one that doesn't use any temp variables:
    $_{$_}++ for @array; print ( ( sort{ $_{$b} <=> $_{$a} } keys %_ )[0] );

    *Note: %_ isn't guaranteed to be around forever :)

    Jasmine

Re: finding the most popular in array
by Anonymous Monk on Sep 10, 2001 at 14:23 UTC
    Thanks for all of your answers!

    Thanks,
    Ralph :)
      I must say, it makes me very happy to read to the end of one of these threads and find that the questioner has troubled to come back and say "thankyou". If only you had a user name and I could vote for your node (if that sounds garbled or faintly suggestive, then I encourage you to join the monastery, when all will become clear, if not All). My take on this Q is the following which may have some time advantage with long arrays because it doesn't count all the elements. Perhaps one loses the advantage on the sort, though. I'd be interested if anybody knows.
      my $max = 0; my $pop; my $cnt = 0; sort @ary; while ($cnt < @ary) { if ($ary[$cnt] eq $ary[$cnt+$max]) { $pop = $ary[$cnt]; while ($ary[$cnt] eq $ary[$cnt+$max]) { $max++; } $cnt += $max } else { $cnt ++; } } print "$pop, the most popular element, appears $max times";


      § George Sherston