Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > Perl > Perl Misc > Sorting a Hash of Arrays by an Element in the Array

Reply
Thread Tools

Sorting a Hash of Arrays by an Element in the Array

 
 
Alf McLaughlin
Guest
Posts: n/a
 
      11-17-2005
Hello all-
I have seen many old questions where people ask if this can be done,
and many responses where people claim it is not possible. However, I
believe I have done it successfully and that it is quite easy:

for my $key (sort {$hash{$a}->[0] <=> $hash{$b}->[0]} keys %hash) {
print "$key\n";
}

Am I missing something??? It looks as if it can be done to me.

Thanks,
Alf

 
Reply With Quote
 
 
 
 
usenet@DavidFilmer.com
Guest
Posts: n/a
 
      11-17-2005
Alf McLaughlin wrote:
> for my $key (sort {$hash{$a}->[0] <=> $hash{$b}->[0]} keys %hash) {
> print "$key\n";
> }
> Am I missing something??? It looks as if it can be done to me.


I dunno. Run this program and tell me what you are trying to say:

#!/usr/bin/perl
use strict; use warnings;
use Data:umper;

my %hash = (col=>[qw/red yellow green/],
make=>[qw/ford chevy/],body=>[qw/coupe sedan/]);

print Dumper (\%hash); #verify the data structure

for my $key (sort {$hash{$a}->[0] cmp $hash{$b}->[0]} keys %hash) {
print "$key\n";
}

__END__

 
Reply With Quote
 
 
 
 
Alf McLaughlin
Guest
Posts: n/a
 
      11-17-2005
I am trying to say you will see the keys printed in the order the 1st
element of the array will be sorted in. I tried this and it worked for
me:

body (coupe is the earliest in the alphabet)
make (ford is the middle)
col (red is the last in the alphabet)

when I changed the first values of the array and played with it, it
always seemed to sort correctly. Actually, this surprised me because I
only expected numbers to sort correctly. I think it may not be sorting
the words correctly, but I'm sure it works for numbers.

http://www.velocityreviews.com/forums/(E-Mail Removed) wrote:
> Alf McLaughlin wrote:
> > for my $key (sort {$hash{$a}->[0] <=> $hash{$b}->[0]} keys %hash) {
> > print "$key\n";
> > }
> > Am I missing something??? It looks as if it can be done to me.

>
> I dunno. Run this program and tell me what you are trying to say:
>
> #!/usr/bin/perl
> use strict; use warnings;
> use Data:umper;
>
> my %hash = (col=>[qw/red yellow green/],
> make=>[qw/ford chevy/],body=>[qw/coupe sedan/]);
>
> print Dumper (\%hash); #verify the data structure
>
> for my $key (sort {$hash{$a}->[0] cmp $hash{$b}->[0]} keys %hash) {
> print "$key\n";
> }
>
> __END__


 
Reply With Quote
 
Paul Lalli
Guest
Posts: n/a
 
      11-17-2005
Alf McLaughlin wrote:

Alf,

Please learn to quote properly. Post your reply *below* the quoted
text, after trimming it down to the relevant bits. Thank you.

[quoting fixed below]

> (E-Mail Removed) wrote:
> > Alf McLaughlin wrote:

[Subject: Sorting a Hash of Arrays by an Element in the Array]
> > > for my $key (sort {$hash{$a}->[0] <=> $hash{$b}->[0]} keys %hash) {
> > > print "$key\n";
> > > }
> > > Am I missing something??? It looks as if it can be done to me.

> >
> > I dunno. Run this program and tell me what you are trying to say:
> >
> > #!/usr/bin/perl
> > use strict; use warnings;
> >
> > my %hash = (col=>[qw/red yellow green/],
> > make=>[qw/ford chevy/],body=>[qw/coupe sedan/]);
> >
> > for my $key (sort {$hash{$a}->[0] cmp $hash{$b}->[0]} keys %hash) {
> > print "$key\n";
> > }
> >
> > __END__

> I am trying to say you will see the keys printed in the order the 1st
> element of the array will be sorted in. I tried this and it worked for
> me:
>
> body (coupe is the earliest in the alphabet)
> make (ford is the middle)
> col (red is the last in the alphabet)


Okay, so obviously that *does* work. So what are you getting at?
Where are these "old questions" you claim to have seen that gave an
incorrect answer? Are you sure they're asking the same thing you're
asking? Give us a point of reference.

> Actually, this surprised me because I
> only expected numbers to sort correctly.


Your example would only sort numbers correctly. David's would only
sort strings correctly. They are not the same. Yours used the <=>
operator, while David's used the cmp operator.

> I think it may not be sorting
> the words correctly, but I'm sure it works for numbers.


Now you've completely lost me. You saw David's example, verified that
it worked, but suddenly you're not sure if it sorted the words
correctly?

Paul Lalli

 
Reply With Quote
 
usenet@DavidFilmer.com
Guest
Posts: n/a
 
      11-17-2005
Alf McLaughlin wrote:
> I tried this and it worked for me:
>
> body (coupe is the earliest in the alphabet)
> make (ford is the middle)
> col (red is the last in the alphabet)
>


But "chevy" (make) comes before "coupe" (body).

 
Reply With Quote
 
Alf McLaughlin
Guest
Posts: n/a
 
      11-17-2005
Paul Lalli wrote:
> Alf McLaughlin wrote:
>
> Alf,
>
> Please learn to quote properly. Post your reply *below* the quoted
> text, after trimming it down to the relevant bits. Thank you.
>
> [quoting fixed below]
>
> > (E-Mail Removed) wrote:
> > > Alf McLaughlin wrote:

> [Subject: Sorting a Hash of Arrays by an Element in the Array]
> > > > for my $key (sort {$hash{$a}->[0] <=> $hash{$b}->[0]} keys %hash) {
> > > > print "$key\n";
> > > > }
> > > > Am I missing something??? It looks as if it can be done to me.
> > >
> > > I dunno. Run this program and tell me what you are trying to say:
> > >
> > > #!/usr/bin/perl
> > > use strict; use warnings;
> > >
> > > my %hash = (col=>[qw/red yellow green/],
> > > make=>[qw/ford chevy/],body=>[qw/coupe sedan/]);
> > >
> > > for my $key (sort {$hash{$a}->[0] cmp $hash{$b}->[0]} keys %hash) {
> > > print "$key\n";
> > > }
> > >
> > > __END__

> > I am trying to say you will see the keys printed in the order the 1st
> > element of the array will be sorted in. I tried this and it worked for
> > me:
> >
> > body (coupe is the earliest in the alphabet)
> > make (ford is the middle)
> > col (red is the last in the alphabet)

>
> Okay, so obviously that *does* work. So what are you getting at?
> Where are these "old questions" you claim to have seen that gave an
> incorrect answer? Are you sure they're asking the same thing you're
> asking? Give us a point of reference.
>
> > Actually, this surprised me because I
> > only expected numbers to sort correctly.

>
> Your example would only sort numbers correctly. David's would only
> sort strings correctly. They are not the same. Yours used the <=>
> operator, while David's used the cmp operator.
>
> > I think it may not be sorting
> > the words correctly, but I'm sure it works for numbers.

>
> Now you've completely lost me. You saw David's example, verified that
> it worked, but suddenly you're not sure if it sorted the words
> correctly?
>
> Paul Lalli


Apologies for the misquoting. This better?

Ah, I've lost you due to my own ignorance. I did not catch that he
changed "<=>" to "cmp"; sorry for the confusion.

I do not have time to dig up old questions for you, but I casually
noticed that some people like to answer this question as "this cannot
be done because you cannot guarantee keys in a hash are stored in a
sorted manner... etc etc". Well, I know that and it's good to know,
but since you can always sort a hash who really cares? The point of me
asking this is actually simple: Can I be guranteed that sorting a Hash
of Arrays like this (on an array element) will always work? That's
really my question. Again, my apologies (this posting has gotten a lot
more apologetic than I had originally intended- from now on I apologize
for nothing in this post! So there.)

But, I have a new question now that is a logical extension of this.
Suppose I have a Hash of a Hash of arrays. Is there a way to sort this
by an element in the array? I know I can write my own subroutine to
create a new hash and sort it that way (or whatever- MTOWTDI), but I
was just curious.

Thanks,
Alf

 
Reply With Quote
 
Alf McLaughlin
Guest
Posts: n/a
 
      11-17-2005
Yea, but chevy is the 2nd element in the array and we're sorting the
first.

 
Reply With Quote
 
Paul Lalli
Guest
Posts: n/a
 
      11-17-2005
Alf McLaughlin wrote:
> Apologies for the misquoting. This better?


Better, yes. Best would be to quote only what is relevant to your
reply. For example, your line above could have come right after my
request that you quote properly. Basically, your quoting should enable
anyone reading just this message to understand what's going on without
having to keep scrolling up or down, or looking at any other message.

> I do not have time to dig up old questions for you, but I casually
> noticed that some people like to answer this question as "this cannot
> be done because you cannot guarantee keys in a hash are stored in a
> sorted manner... etc etc".


I'm afraid I simply fail to believe you. I am far more inclined to
believe that there is a difference between the questions you are
referring to, and the question you actually asked. Yes, what you asked
is obviously very possible. It is entirely likely that another post
was asking a similar, but different enough, question.

> The point of me
> asking this is actually simple: Can I be guranteed that sorting a Hash
> of Arrays like this (on an array element) will always work? That's
> really my question.


I don't really get what you mean by this question. If you have a hash
of arrays, can you always obtain a list of keys of that hash, sorted by
the X'th element of the 'inner' arrays of the hash? Yes.

> But, I have a new question now that is a logical extension of this.
> Suppose I have a Hash of a Hash of arrays. Is there a way to sort this
> by an element in the array?


First: You need to use better terminology. There is no such thing as
sorting a hash. What you can do is obtain a list of keys of that hash,
and sort that list of keys. You can then operate on a sorted list of
keys. The hash itself, however, cannot be sorted.

Second: Yes, of course you can. Using the same technique you already
demonstrated, but with one extra dimension:

my @sorted_keys = sort { $a->{key}[0] cmp $b->{key}[0] } %big_hash;

This will obtain a list of all of %big_hash's keys, sorted by the order
of the first element of the array referenced by the value of the hash
at the key 'key'.

Paul Lalli

 
Reply With Quote
 
Eden Cardim
Guest
Posts: n/a
 
      11-17-2005
> I do not have time to dig up old questions for you, but I casually
> noticed that some people like to answer this question as "this cannot
> be done because you cannot guarantee keys in a hash are stored in a
> sorted manner... etc etc".


You're missing the point, there's quite a big difference between
"sorting" and "ordering". Hashes aren't ordered in any way because of
the nature of the algorithmic procedure behind their building process.
You can, however, sort the keys, or values, or both in a particular
manner, if you'd like.

> Well, I know that and it's good to know, but since you can always sort a hash who really cares?


Wrong, this is VERY relevant, since hashes aren't ordered, they can't
remember the order in which the elements were stored in them. If you
use a hash-based data-structure to store, say, an XML document, you
won't be able to do round-tripping. If your XML happens to be an HTML
document, everyone will care when you render your page ad hoc.

 
Reply With Quote
 
Alf McLaughlin
Guest
Posts: n/a
 
      11-17-2005
Geez, sorry I didn't ask my question like you would of; I guess you
rule. Anyway, thanks for the info.

 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
hash of hash of hash of hash in c++ rp C++ 1 11-10-2011 04:45 PM
Hash#select returns an array but Hash#reject returns a hash... Srijayanth Sridhar Ruby 19 07-02-2008 12:49 PM
Benchmark segfault [Was: Array#inject to create a hash versus Hash[*array.collect{}.flatten] ] Michal Suchanek Ruby 6 06-13-2007 04:40 AM
Array#inject to create a hash versus Hash[*array.collect{}.flatten] -- Speed, segfault Anthony Martinez Ruby 4 06-11-2007 08:16 AM
[Nuby] Sorting a Hash and keepint it as a Hash? Williams, Chris Ruby 3 12-13-2004 09:04 PM



Advertisments