Beefy Boxes and Bandwidth Generously Provided by pair Networks
Keep It Simple, Stupid

sort hash by value

by convenientstore (Pilgrim)
on Dec 02, 2007 at 17:49 UTC ( #654433=perlquestion: print w/replies, xml ) Need Help??
convenientstore has asked for the wisdom of the Perl Monks concerning the following question:

What is the best way to sort the hash by value and printing out the top 5 results? For array, I guess you can do something like
@count_s = sort { $reportn{$a} <=> $reportn{$b}; } @count_s; foreach (@count_s[0..4]) { print "$_ ====> $reportn{$_}\n"; }
But not sure about hash as below method does not work.
is it just my grammar mistake?
foreach my $hero ( sort keys %total_o) { if ($reportn_o{$hero}) { @reportnL = sort { $total_o{$a} <=> $total_o{$b} } values (%t +otal_o{$hero}); } } for (@reportnL[0..4]) { print "$_\n"; }

Replies are listed 'Best First'.
Re: sort hash by value
by salva (Abbot) on Dec 02, 2007 at 19:55 UTC
    Sorting the full list of items to get just the top n is not the most efficient way, there are better algorithms. See Selection_algorithm.

    You can also use Sort::Key::Top instead of implementing those algorithms yourself ;-)

Re: sort hash by value
by moritz (Cardinal) on Dec 02, 2007 at 18:01 UTC
    Since you can't reverse a hash in the general case, you can just make a list of lists:
    my @list = map { [$_, $hash{$_}] } keys %hash; # sort it: @list = sort { $a->[1] cmp $b->[1] }; # now you can print it
Re: sort hash by value
by grep (Monsignor) on Dec 02, 2007 at 18:11 UTC
    I'm not quite sure what your doing with all that code, there seem to be quite a few mistakes. Which makes it hard for me to follow.

    But as to your main point of the sort not working: You're sending in the values but treating them like keys and trying to do a lookup.
    @reportnL = sort { $total_o{$a} <=> $total_o{$b} } values (%total_o{$hero});

    Change it to
    @reportnL = sort { $total_o{$a} <=> $total_o{$b} } keys %total_o ;

    UPDATE: Just noticed his was my 500th post.

    One dead unjugged rabbit fish later...
Re: sort hash by value
by johngg (Abbot) on Dec 02, 2007 at 18:44 UTC
    for (@reportnL[0..4]) { print "$_\n"; }

    Your use of an array slice here seems a little unusual, not incorrect but not the way I suspect most would approach the task. I would perhaps do

    for ( 0 .. 4 ) { print qq{$reportnL[$_]\n}; }

    or, more probably

    print qq{$reportnL[$_]\n} for 0 .. 4;

    I hope this is of interest.



Log In?

What's my password?
Create A New User
Node Status?
node history
Node Type: perlquestion [id://654433]
Approved by grep
[LanX]: do you know the story of the triangle player?
[choroba]: Oh, the Czech one playing the German composition?
[choroba]: BTW, the elections are over. We already have the final results.
[choroba]: I should probably apply for a job somewhere abroad.
[LanX]: nope this one One day the triangle player of an orchestra gets very ill and goes to the hospital.. ..

How do I use this? | Other CB clients
Other Users?
Others musing on the Monastery: (8)
As of 2017-10-21 19:34 GMT
Find Nodes?
    Voting Booth?
    My fridge is mostly full of:

    Results (270 votes). Check out past polls.