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

Hi Monks,

I need to sort my list of hash values alphabetically. I know how to sort the keys already, but swapping my keys for values won't work here as some of the values are the same. My Hash list looks like this:

my %hash = { 5328 => High 26191 => Very High 57491 => Low 4915 => High 1499 => Very High 999 => Low 4323 => Average 4314 => High

The code I have to sort the list by keys looks like this:

foreach my $key ( sort keys %hash ) { print "key: " . $key . " value: " . $hash{$key} . "\n"; }

Scowered through some of the 'howto's' for this, but none seem to have any info on sorting when some values might be the same. A simple link would be great.

Replies are listed 'Best First'.
Re: Sort Hash Values Alphabetically
by kennethk (Abbot) on May 25, 2010 at 14:19 UTC
    This is a FAQ: How do I sort a hash (optionally by value instead of key)?. Copied from that link:

    my @keys = sort { $hash{$a} cmp $hash{$b} } keys %hash;

    See also sort for how to construct a custom sorting function. Note that since some of your values are duplicates, a sort is not guaranteed stable, i.e. you can get different results from subsequent executions. If this matters, you can add an extra term to your sort so it sorts first by value then by a guaranteed unique quantity, the key:

    my @keys = sort { $hash{$a} cmp $hash{$b} or $a cmp $b} keys %hash;

      That link's (how do I sort a hash) all I need. Cheers.
Re: Sort Hash Values Alphabetically
by ack (Deacon) on May 25, 2010 at 16:27 UTC

    Per kennethk's suggested reference, here's one way that's pretty straight-forward:

    use strict; use warnings; my %hash = ( 5328 => 'High', 26191 => 'Very High', 57491 => 'Low', 4915 => 'High', 1499 => 'Very High', 999 => 'Low', 4323 => 'Average', 4314 => 'High', ); print "$_ => $hash{$_}\n" foreach(sort{$hash{$a} cmp $hash{$b}} keys %hash);

    Which yields the output that I think you're looking for:

    4323 => Average 4314 => High 5328 => High 4915 => High 57491 => Low 999 => Low 1499 => Very High 26191 => Very High

    The sort doesn't care that you have duplicate entries, it treats them as eq in the cmp and doesn't change their order within the duplicates...but it does group the duplicates and puts the group in the right place in the sort.

    Good luck.

    ack Albuquerque, NM