CGI/Perl Guide | Learning Center | Forums | Advertise | Login
Site Search: in

  Main Index MAIN
INDEX
Search Posts SEARCH
POSTS
Who's Online WHO'S
ONLINE
Log in LOG
IN

Home: Perl Programming Help: Intermediate:
sorting a hash through multiple levels of keys

 



random_seb
New User

Apr 16, 2009, 12:07 PM

Post #1 of 5 (550 views)
sorting a hash through multiple levels of keys Can't Post

heya,
I have been search google for hours trying to figure out a way to do this straight up. I have a hash of hashes structured as such:


Code
hash->{'ip'}->{$ip}->{'port'}->{$port}->{'packets'} = 20; 
hash->{'ip'}->{$ip}->{'port'}->{$port}->{'time'} = time;
etc


(for purposes of importing into xml::simple)

How would I go about sorting that by the 'packets' field, using the sort functions of perl, without having to go through hoops converting the data into different formats first?

All of the multiple level hash examples of sort that I can find assume only one level of dynamic keys, such as :


Code
sort { hash->{'ip'}->{$b}->{'packets'} <=> hash->{'ip'}->{$a}->{'packets'} }  keys %{hash->{'ip'}};


Any hints or ideas would be welcome..


(This post was edited by random_seb on Apr 16, 2009, 12:32 PM)


1arryb
User

Apr 17, 2009, 8:03 AM

Post #2 of 5 (539 views)
Re: [random_seb] sorting a hash through multiple levels of keys [In reply to] Can't Post

Hi random,

This problem was discussed in a thread over at perl monks. Check out davidw's solution http://www.perlmonks.org/?node_id=474152. Let us know if you can't get it working.

Cheers,

Larry


1arryb
User

Apr 17, 2009, 8:38 AM

Post #3 of 5 (538 views)
Re: [1arryb] sorting a hash through multiple levels of keys [In reply to] Can't Post

Random,

I thought this was an interesting problem, so I worked out davidw's idea for your use case.
Note that this solution does, in fact, transform (i.e., flatten) your hash into an array for the sort. I don't see anyway around that.

Code
#!/usr/bin/perl 

use strict;
use warnings;
use Dumpvalue;

# Dummy up some test data.
my $hash = {
ip => {
'192.168.0.1' => {
port => {
1000 => {
packets => 20,
time => '200ms'
},
1020 => {
packets => 10,
time => '100ms'
},
2020 => {
packets => 50,
time => '400ms'
}
}
},
'192.168.0.2' => {
port => {
1000 => {
packets => 220,
time => '600ms'
},
1020 => {
packets => 105,
time => '200ms'
},
2020 => {
packets => 1,
time => '0ms'
}
}
}
}
};

# Flatten the hash to an array and sort by #packets.
my @values = sort { $a->[2] <=> $b->[2] }
map {
my $k = $_;
map { [ $k, $_, $hash->{ip}->{$k}->{port}->{$_}->{packets}, $hash->{ip}->{$k}->{port}->{$_}->{time} ] }
keys(%{$hash->{ip}->{$k}->{port}});
} keys (%{$hash->{ip}});

map { print "@$_\n" } @values;


Cheers,

Larry


(This post was edited by 1arryb on Apr 17, 2009, 11:20 AM)


random_seb
New User

Apr 17, 2009, 9:04 AM

Post #4 of 5 (535 views)
Re: [1arryb] sorting a hash through multiple levels of keys [In reply to] Can't Post

That's perfect, thanks! Cool

I am going to have to spend some time playing around with map, to get a feel for it, it seems to be a pretty powerful tool


KevinR
Veteran


Apr 17, 2009, 10:50 AM

Post #5 of 5 (531 views)
Re: [1arryb] sorting a hash through multiple levels of keys [In reply to] Can't Post

Nice one Larry.
-------------------------------------------------

 
 


Search for (options) Powered by Gossamer Forum v.1.2.0

Web Applications & Managed Hosting Powered by Gossamer Threads
Visit our Mailing List Archives