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

I am trying to print out the members of a multidimensional associative array according to their popularity. Assume, for example, that my array is built using the following data:
$my_associative_array{"Key1"}=[qw(a b b b a a c d b d b)]; $my_associative_array{"Key2"}=[qw(c a b a b d c c d d d e f)];
I am trying to get output such as follows:

Key1:
b = 5
a = 3
d = 2
c = 1

Key2:
d = 4
c = 3
a = 2
b = 2
e = 1
f = 1

As you can see, the output is sorted according to the number of times the data appears in the array. I'm sure this is probably easy for some of you perl guru's out there, but I sure am strugling with it. Any help is most appreciated. And by the way, what a wonderful site!

edited: Sat Aug 3 02:30:33 2002 by jeffa - code tags

  • Comment on Finding most popular order in a multidimensional associative array
  • Download Code

Replies are listed 'Best First'.
(jeffa) Re: Finding most popular order in a multidimensional associative array
by jeffa (Bishop) on Aug 03, 2002 at 03:10 UTC
    I am sure this can be golfed down, but here goes:
    use strict; my %hash = ( Key1 => [qw(a b b b a a c d b d b)], Key2 => [qw(c a b a b d c c d d d e f)], ); for (sort keys %hash) { my %counted; $counted{$_}++ for @{$hash{$_}}; print "$_:\n"; for (sort { $counted{$b} <=> $counted{$a} } keys %counted) { print "\t$_ = $counted{$_}\n"; } }

    jeffa

    L-LL-L--L-LL-L--L-LL-L--
    -R--R-RR-R--R-RR-R--R-RR
    B--B--B--B--B--B--B--B--
    H---H---H---H---H---H---
    (the triplet paradiddle with high-hat)
    
      Thank you so very much! One additional question though. What would be the easiest way to list only the top "X" number of the most popular items?
        Hey ... this isn't homework is it? ;)

        A for loop works on a list. The inner for loop iterates on the sorted keys of the hash %counted, what we could do is specify a subscript for that list. First, a simple example:

        use strict; my @array = (0..999); # retrieve only the first 10 elements: my @top_ten = @array[0..9]; print "$_\n" for @top_ten;
        So, if we want to only display the top 3 most popular items, we could do this:
        # ... original code for ((sort { $counted{$b} <=> $counted{$a} } keys %counted)[0..2]) { # ... etc. }
        If you want to avoid hard-coding the number, be sure and subtract 1, or start the subscript at 1:
        # pick one: my $max = 2; # use [0..$max] my $max = 3; # use [1..$max] or [0..$max-1]

        jeffa

        L-LL-L--L-LL-L--L-LL-L--
        -R--R-RR-R--R-RR-R--R-RR
        B--B--B--B--B--B--B--B--
        H---H---H---H---H---H---
        (the triplet paradiddle with high-hat)