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: Beginner:
sorting hash of Arrays dilema

 



rooroo
Deleted

Jun 12, 2001, 5:47 AM

Post #1 of 3 (848 views)
sorting hash of Arrays dilema Can't Post

Hello !

I am having problems sorting ARRGHHHH!! , can anyone please help!!!!

I have for example :-

%HoA = (
"flintstones" => [ "fred", "barney", "wilma" ],
"jetsons" => [ "george", "jane", "elroy" ] ,
"simpsons" => [ "homer", "marge", "bart" ]
);

I am trying to sort on barney jane marge so when it prints barney should come first - if you see what i mean!

foreach $familyname (sort {&sortby_name} keys %HoA) {
print "$familyname $HoA{$familyname[1]}";
}

sub sortby_name (
$HoA{$keyfamily}[1]{$a} cmp $HoA{$keyfamily}[1]{$b};

);



Jasmine
Administrator / Moderator

Jun 12, 2001, 11:00 AM

Post #2 of 3 (842 views)
Re: sorting hash of Arrays dilema [In reply to] Can't Post

There were a few problems with the code.


In Reply To

Code
foreach $familyname (sort {&sortby_name} keys %HoA) { 
print "$familyname $HoA{$familyname[1]}";
}


This problem could have easily have been found by using strict. When running this program, you would have seen the following error:

Global symbol @familyname requires explicit package name at...

Now if you're wondering where that array came from, it's right here:


Code
$HoA{$familyname[1]}

$familyname[1] is referring to the second element of array @familyname, not to the second array element of a HoA.

So there's one. Here's two more:


In Reply To

Code
sub sortby_name ( 
$HoA{$keyfamily}[1]{$a} cmp $HoA{$keyfamily}[1]{$b};

);


Parenthesis () were being used instead of curly braces {}. The parens and ; were hiding the fact that sortby_name was really supposed to be a subroutine.

And in the next line, one too many levels were added :)


In Reply To

Code
$HoA{$keyfamily}[1]{$a} cmp $HoA{$keyfamily}[1]{$b};


should be:


Code
$HoA{$a}[1] cmp $HoA{$b}[1]

Where was $keyfamily defined? Another thing that would have been caught if you used strict.

So, corrected the code will make it look like this:


Code
foreach my $familyname (sort { &sortby_name } keys %HoA) { 
print "$familyname $HoA{$familyname}[1]";
}

sub sortby_name {
$HoA{$a}[1] cmp $HoA{$b}[1];
}

But I hardly ever offer this much explanation without playing the devil's advocate:

What if you wanted to sort a different HoA? What if you wanted to sort on a different column? What if you wanted to sort alphabetically instead of asciibetically?

In the method previously used, you would need to create a subroutine for each variation of the sort subroutine. But here's an alternative:


Code
foreach my $familyname ( sort { sort_hoa( 1, \%HoA ) } keys %HoA ) { 
print "$familyname - $HoA{$familyname}[1]\n";
}

sub sort_hoa {
my ( $index, $HoA ) = @_;
lc( $HoA->{$a}[$index] ) cmp lc($HoA->{$b}[$index]);
}

sort_hoa( 1, \%HoA ) means that sort_hoa is being passed 2 variables: the first is the column that you want to sort, and the second is a reference to the hash that you want to sort.

Now for the new sorting sub:


Code
sub sort_hoa { 
my ( $index, $HoA ) = @_;
lc( $HoA->{$a}[$index] ) cmp lc($HoA->{$b}[$index]);
}

Here, $index and $HoA are being assigned the variables that were passed to it. the lc is temporarily converting the variables to lower case for comparison so we get true alphabetical sorting.

So in the future, if you wanted to sort a different hash or arrays on a different column, you can use the same subroutine and just change the variables that's passed to the sort sub.


Code
sort_hoa( 2, \%next_hoa );   
sort_hoa( 90, \%huge_hoa );

Hope this helps!



rooroo
Deleted

Jun 13, 2001, 5:51 AM

Post #3 of 3 (824 views)
Re: sorting hash of Arrays dilema [In reply to] Can't Post

Hello Jasmine

Thank you very much for your time and effort regarding my post.

This has been a great help to me!!

I hang my head in shame regarding the parenthesis i used for the subroutine instead of curly braces - my actual code (this was just a quick alternative to get the point across) did use curly braces, so that part was just foolish me in rush.


I think one of the lessons here is to use strict!

I am currently studying the alternative method you provided - just gotta get my head round it!

Thankyou once again
Phil


 
 


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

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