Sorting keys of hash table by values

by iman_saleh (Novice)
 on Jan 31, 2008 at 21:25 UTC Need Help??

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

Hi all, I want to sort the keys of a hash table according to the values these keys are pointing to in descending order, I only found that using:
```@sortedKeys = sort { \$h{\$a} <=> \$h{\$b} } keys %h;
does that but the sorting is ascending. Can anyone help me find the way to make it sort descending instead? Thanks,

Replies are listed 'Best First'.
Re: Sorting keys of hash table by values
by samtregar (Abbot) on Jan 31, 2008 at 21:28 UTC
@sortedKeys = sort { \$h{\$b} <=> \$h{\$a} } keys %h;

-sam

Re: Sorting keys of hash table by values
by ikegami (Patriarch) on Jan 31, 2008 at 21:53 UTC
You guys missed
```@sortedKeys = sort { -( \$h{\$a} <=> \$h{\$b} ) } keys %h;
:)
Re: Sorting keys of hash table by values
by kyle (Abbot) on Jan 31, 2008 at 21:38 UTC

Just reverse sort:

```@sortedKeys = reverse sort { \$h{\$a} <=> \$h{\$b} } keys %h;

Bad. reverse means extra operations and making a second list that is the same size as the original.

The first reply is the best, as it does not involve any extra operations.

--rjray

I thought you might say that (and by "you", I mean "somebody").

```use Benchmark  qw( cmpthese );
use List::Util qw( shuffle );

my @set = shuffle 1 .. 1_000_000;

cmpthese( 100,
{ 'sort' => sub { my @x = sort { \$b <=> \$a } @set; return; }
+,
'rsort' => sub { my @x = reverse sort { \$a <=> \$b } @set;
+return; },
} );
__END__
Rate  sort rsort
sort  1.01/s    --   -2%
rsort 1.03/s    2%    --

(As I recall, 2% is within the margin of error for Benchmark.)

In perl (the implementation of Perl), there's a special case for reverse sort so that it doesn't have the performance penalty you might otherwise expect it to have. That being the case, the main difference between reverse sort { \$a cmp \$b } and sort { \$b cmp \$a } is how they read to the programmer. I think that it's far more obvious what's going on when you reverse sort especially as the expressions involved become more complicated. It could be pretty easy to lose the \$a and \$b in a big block. Even if it were not optimized, I think you'd have to have a pretty long list before the performance penalty outweighs the maintainability benefit.

This also means there's no performance penalty for reverse sort { \$b <=> \$a }, but that's just rude.

Did you try it?
I thought that too but testing samtregar and kyles versions took the same time. Ikegamis version is about 6% slower.

Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: perlquestion [id://665449]
Approved by samtregar
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others contemplating the Monastery: (5)
As of 2024-03-01 03:46 GMT
Voting Booth?
My favourite way to spend a leap day ...

Results (28 votes). Check out past polls.