Slavatron
Slavatron

Reputation: 2358

In Perl, how do I print hash keys in order of their (numerical) values?

I have a hash in which the keys are strings and the values are single-digit numbers; here's a slice of said hash:

      'f92a0d43-a230-4bfd-b580-9eac5e0ce6cf' => 7,
      '26c4b622-969f-4861-bbab-dd506ea4b00a' => 1,
      'afb1f925-4109-4b1d-967f-3958106e0bc3' => 3,
      'a099a6dc-0c66-4683-94c3-29d6ef6947fd' => 1,
      'e71c4860-224d-4b8d-ae9e-4700e9e65a97' => 2,

I want print the keys in order of descending values. So for the slice listed there, the output would be:

       'f92a0d43-a230-4bfd-b580-9eac5e0ce6cf' => 7
       'afb1f925-4109-4b1d-967f-3958106e0bc3' => 3
       'e71c4860-224d-4b8d-ae9e-4700e9e65a97' => 2
       '26c4b622-969f-4861-bbab-dd506ea4b00a' => 1
       'a099a6dc-0c66-4683-94c3-29d6ef6947fd' => 1

The order of keys with identical values does not matter. Answers to this question: In Perl, how can I print the key corresponding to the maximum value in a hash? suggest using the sort function; which I have:

  my @values = sort { $b <=> $a } values %ID_hash;

What I am having trouble with is actually printing the keys in the order.

I tried:

    foreach(@values) {
        my $cur = $_;
        print "$ID_hash{$cur}\t$cur\n";
    }

Which fails because I'm supplying values rather than keys.

I know I can always just print the key/value pairs as a tab-separated file and use the Unix version of sort but I'm sure there's a way to do this with Perl. Any help will be much appreciated.

Upvotes: 3

Views: 1382

Answers (1)

Zaid
Zaid

Reputation: 37146

Sort the keys by the values in the hash, then use the sorted keys to print.

for my $key ( sort { $ID_hash{$b} <=> $ID_hash{$a} } keys %ID_hash ) {
    print join( "\t", $key, $ID_hash{$key} ), "\n";
}

This equivalent may be a little clearer:

my @sorted_keys = sort { $ID_hash{$b} <=> $ID_hash{$a} } keys %ID_hash ;

print "$_\t$ID_hash{$_}\n" for @sorted_keys;

Upvotes: 9

Related Questions