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.

 



Wiliam
Novice

Aug 8, 2000, 4:30 AM

Post #1 of 10 (1155 views)
Sorting a hash. Can't Post

Hi Folks,

I'm trying to sort a hash alphabeticaly but I'm having problems. I want to sort the values of the hash not the keys in alphabetical form. I have the following lines of code.

if ($term) {
if ($field =~ /$term/ig) {
$tobesorted{$file} = $e_dat_name;
}

&print_results(%tobesorted);

I need to sort the hash %tobesorted before passing it onto the next subroutine. Does anyone have any ideas?

Thankyou!

Wiliam.


Kanji
User

Aug 7, 2000, 10:16 PM

Post #2 of 10 (1155 views)
Re: Sorting a hash. [In reply to] Can't Post

You wanna sort the hash inside your sub. Using japhy's example ...

<BLOCKQUOTE><font size="1" face="Arial,Helvetica,sans serif">code:</font><HR>

&print_results(%tobesorted);

sub print_results {
my %hash = @_;
for (sort keys %hash) {
# $_ is key, $hash{$_} is value
# ASCIIbetically sorted by key}
print "$_: $hash{$_}\n";
}
}</pre><HR></BLOCKQUOTE>


japhy
Enthusiast

Aug 8, 2000, 5:47 AM

Post #3 of 10 (1155 views)
Re: Sorting a hash. [In reply to] Can't Post

You don't sort hashes, really. Perl keeps them sorted in its own internal order, which would make little sense to you.

What you can do, though, is sort the keys and access the values in that specific order:

<BLOCKQUOTE><font size="1" face="Arial,Helvetica,sans serif">code:</font><HR>


for (sort keys %hash) {
# $_ is key, $hash{$_} is value
# ASCIIbetically sorted by key
}

for (sort { $hash{$a} <=> $hash{$b} } keys %hash) {
# $_ is key, $hash{$_} is value
# ASCIIbetically sorted by value
}
</pre><HR></BLOCKQUOTE>

------------------
Jeff "japhy" Pinyan -- accomplished author, consultant, hacker, and teacher



Wiliam
Novice

Aug 8, 2000, 6:36 AM

Post #4 of 10 (1155 views)
Re: Sorting a hash. [In reply to] Can't Post

That's not exactly what I was looking for, thanks anyway.

I've got a hash table. I need to sort the table according to the values in alphabetical order.

Any clues as to how to do that?

Thanks!


dws
Deleted

Aug 8, 2000, 9:07 AM

Post #5 of 10 (1155 views)
Re: Sorting a hash. [In reply to] Can't Post

"I need to sort the hash %tobesorted before passing it onto the next subroutine."

Your wording suggests that you don't understand how Perl hashes behave. Please carefully re-read what japhy wrote. He's pointing you in the right direction.




Cameron
Deleted

Aug 8, 2000, 12:51 PM

Post #6 of 10 (1155 views)
Re: Sorting a hash. [In reply to] Can't Post

 sort the hash %tobesorted before passing it onto the next subroutine. Does anyone have any ideas?

I would suggest putting the sort into your subroutine.Alternatively, you can make a list of sorted key value pairs, and pass that to the subroutine.


@sorted_pairs=
sort{$a->[1] cmp $b->[1]}
map{[$_,$hash{$_}]}keys %hash;

foreach(@sorted_pairs){
print "key:$_->[0]\tVal:$_->[1]\n";
}


Wiliam
Novice

Aug 9, 2000, 12:13 AM

Post #7 of 10 (1155 views)
Re: Sorting a hash. [In reply to] Can't Post

Hello Everyone,

Thankyou for all your helpful replies.

I still don't quite understand how to go abotu this, though.

What I really want to do is to create a new hash table that is sorted from the old hash table.

That is. I have the following hash:

%tobesorted

I want to sort the above alphabeticaly according to the values of the hash, not the keys and from that create a new hash that is in sorted order.

Thanks for all your help!

Wil.



Kanji
User

Aug 9, 2000, 3:57 AM

Post #8 of 10 (1155 views)
Re: Sorting a hash. [In reply to] Can't Post

That's already been asked and answered.

See japhy's message, particularly the ASCIIbetically sorted by value example. It shouldn't be hard for you at all to modify my example subroutine to account for the differences.

You appear to be getting hung up on the notion that hashes themselves can be ordered, which just isn't the case: if you want a hash to be ordered in any fashion, you have to order it yourself with sort.

If you want to pass around a new ordering, a better option would be to create an array of the keys in the order of your sorted values (ie, my @keys_of_sorted_values = sort { $tobesorted{$a} <=> $tobesorted{$b} } keys %tobesorted;) and then pass that around with your hash by reference.

<BLOCKQUOTE><font size="1" face="Arial,Helvetica,sans serif">code:</font><HR>

&print_results( \@keys_of_sorted_values, %tobesorted );
# Note the \ before @!

sub print_results {
my $order = shift; # Note $ not @!
my %hash = @_;

foreach my $key ( @$order ) {
print $hash{$key};
}
}</pre><HR></BLOCKQUOTE>


japhy
Enthusiast

Aug 9, 2000, 5:06 AM

Post #9 of 10 (1155 views)
Re: Sorting a hash. [In reply to] Can't Post

You don't seem to be understanding the chief
issue here, Wil. Hashes CAN NOT be sorted.
There is no such thing in Perl as a sorted
hash -- the ONLY thing you can do is iterate
over the keys in a specific order. Example:

<BLOCKQUOTE><font size="1" face="Arial,Helvetica,sans serif">code:</font><HR>


%hash = qw(
mine yours
his hers
ours theirs
Jack Jill
);

for (sort keys %hash) {
print "$_ and $hash{$_}\n";
}
# this prints:
# Jack and Jill
# his and hers
# mine and yours
# ours and theirs

for (sort { $hash{$a} cmp $hash{$b} } keys %hash) {
print "$_ and $hash{$_}\n";
}
# this prints:
# Jack and Jill
# his and hers
# ours and theirs
# mine and yours
</pre><HR></BLOCKQUOTE>

The first sorted list of keys is the keys in
ASCIIbetical order. The second sorted list
of keys is the keys based on the VALUES in
ASCIIbetical order. Notice: J, h, m, o, in
the first list (the starting letters of the
KEYS) vs. J, h, t, y, in the second list (the
starting letters of the VALUES).

------------------
Jeff "japhy" Pinyan -- accomplished author, consultant, hacker, and teacher



Wiliam
Novice

Aug 14, 2000, 1:15 AM

Post #10 of 10 (1155 views)
Re: Sorting a hash. [In reply to] Can't Post

Japhy,

I've tried implenting your suggestion into my code and it works fine. Well, just about.
I've now modified my script to contain the following code:

for (sort { $tobesorted{$a} <=> $tobesorted{$b} } keys %tobesorted) {
# $_ is key, $hash{$_} is value
# ASCIIbetically sorted by value
$sorted{$_} = $hash{$_};
}

This creates a new hash called %sorted with the keys and values sorted. That's what I want. But for some reason the sorted list is not sorted alphabeticaly from A-Z. Any ideas why is this?

Thankyou!

Wiliam.

 
 


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

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