Beefy Boxes and Bandwidth Generously Provided by pair Networks
Just another Perl shrine

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
and all is quiet...

How do I use this? | Other CB clients
Other Users?
Others studying the Monastery: (3)
As of 2018-04-22 02:03 GMT
Find Nodes?
    Voting Booth?