Beefy Boxes and Bandwidth Generously Provided by pair Networks
Don't ask to ask, just ask
 
PerlMonks  

How to sort HASH?

by iwanthome (Beadle)
on Apr 05, 2004 at 09:14 UTC ( [id://342595]=perlquestion: print w/replies, xml ) Need Help??

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

I have a hash which contain netflow statistic data. And I want to sort it by total number of packets and total size.

My code is like this:

%flows = sort {$flows{$b}{pkts} <=> $flows{$a}{pkts} or $flows{$b}{size} <=> $flows{$a}{size} } %flows;

But why not it work normal? What's wrong with it?

thanks!

Replies are listed 'Best First'.
Re: How to sort HASH?
by borisz (Canon) on Apr 05, 2004 at 09:18 UTC
    You can not reorder the hash, you want to order the keys of the hash.
    @ordered_keys = sort {$flows{$b}{pkts} <=> $flows{$a}{pkts} or $flows{$b}{size} <=> $flows{$a}{size} } keys %flo +ws;
    Boris

      thanks! I have a stupid error.

      I will try to sort the keys of the hash

Re: How to sort HASH?
by Limbic~Region (Chancellor) on Apr 05, 2004 at 12:14 UTC
    iwanthome,
    If you are going to be adding/removing/updating keys and values, but you want the hash to always be sorted when accessing it, you can use Tie::Hash::Sorted.
    use Tie::Hash::Sorted; my $custom_sort = sub { my $hash = shift; [ sort { $hash->{$b}{pkts} <=> $hash->{$a}{pkts} || $hash->{$b}{size} <=> $hash->{$a}{size} } keys %$hash ]; }; tie my %flows, 'Tie::Hash::Sorted', 'Sort_Routine' => $custom_sort, 'Optimization' => 'none' ; for ( keys %flows ) { # Will always be sorted the way you want }
    If you encounter any bugs, let me know and I will try to fix them.

    Cheers - L~R

Re: How to sort HASH?
by u235sentinel (Hermit) on Apr 05, 2004 at 17:30 UTC
    I had a similar project awhile back. I had pulled ip addresses from my apache access log and wanted to see how many times a certain ip hit our web site. Basically I used the ip addresses as the hash keys and the value was incremented for each instance. Everyone told me I could not sort by the values (sounds like you want to do the same thing here). I did notice in the perl cookbook something that worked in sorting the values... sorta :-) Long story shore, I was able to sort / print the values in order. Worked great! Here is the sorting of the hash I used. Hopefully this will help:
    # This section will count the number of times we see an ip address open ACCESSLISTIPS, "access_log_ips" or die "The file could not be opened ($!)"; chomp(@ips = <ACCESSLISTIPS>); foreach $ip (@ips) { $count{$ip} += 1; } # This routine will sort the values of a hash then print them out for +us. # foreach $ip (sort { $count{$a} cmp $count{$b} } keys %count) { print "$ip was seen $count{$ip} times.\n"; }
      u235sentinel,
      Everyone told me I could not sort by the values

      Since this is your first write-up on this site, I will assume you mean everyone somewhere else told you this. I believe this may have been a misunderstanding by you, them or likely both. You can get the keys of the hash returned to you in sorted order by any abitrary sorting method you want. The hash itself is still stored internally in its own order. This means you have to repeat the sort routine each time you want to view the hash sorted. There are modules that do the sorting for you under the covers given the appearance of a sorted hash.

      I was able to sort / print the values in order

      I hope you did not use the code you are showing here. You are using cmp when you should be using <=>. The difference is textual comparison versus numerical. Do you really want 2 coming after 10?

      Welcome to the Monastery! - L~R
        oops ..

        Yes I did use this code and now I see I was a 'little' too quick to push it out. But then again, I'm a noob still. Thx for the tip. I made the change and tested it against my access list. So cmp does a text comparison? That part was unclear. :-)

        I will assume you mean everyone somewhere else told you this

        Yup. It was in speaking with my co-workers. Seems I was lead astray :-)

        Thx again!

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: perlquestion [id://342595]
Approved by Corion
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others avoiding work at the Monastery: (6)
As of 2024-04-18 02:47 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found