Sort on multiple values

F

Frank

Hi,

I've been trying to sort an hash on multiple items, but at the moment
with no success.

I got this script:

%hash = (
'one' =>
{'1'=>'a','2'=>'m'},
'two' =>
{'1'=>'a','2'=>'k'},
'thr' =>
{'1'=>'b','2'=>'b'},
'fou' =>
{'1'=>'c','2'=>'l'},
'fiv' =>
{'1'=>'a','2'=>'d'},
'six' =>
{'1'=>'a','2'=>'f'},
'sev' =>
{'1'=>'b','2'=>'f'},
'eig' =>
{'1'=>'a','2'=>'e'},
);

%hash_sort = sort {
$hash{$a}{'1'} cmp $hash{$b}{'1'} || $hash{$a}{'1'} cmp $hash{$b}{'2'}
} keys(%hash);

foreach $key(%hash_sort) {
print "Test: ($key) ".$hash{$key}{'1'}." - " . $hash{$key}{'2'} . "\n";
}


But I seems to just return it in some random order.

What could be wrong?


Regards,

Frank
 
A

anno4000

Frank said:
Hi,

I've been trying to sort an hash on multiple items, but at the moment
with no success.

Well, you *can't* sort a hash, so the lack of success is no surprise.
Hash entries have no defined order.
I got this script:

%hash = (
'one' =>
{'1'=>'a','2'=>'m'},
'two' =>
{'1'=>'a','2'=>'k'},
'thr' =>
{'1'=>'b','2'=>'b'},
'fou' =>
{'1'=>'c','2'=>'l'},
'fiv' =>
{'1'=>'a','2'=>'d'},
'six' =>
{'1'=>'a','2'=>'f'},
'sev' =>
{'1'=>'b','2'=>'f'},
'eig' =>
{'1'=>'a','2'=>'e'},
);

%hash_sort = sort {
$hash{$a}{'1'} cmp $hash{$b}{'1'} || $hash{$a}{'1'} cmp $hash{$b}{'2'}
} keys(%hash);

Your sort block looks fine, but it is nonsense to assign the list of
hash keys to another hash. You don't even know if there's an even or
odd number of elements in it.

Try this (untested):

my @ordered_keys = sort {
$hash{$a}{'1'} cmp $hash{$b}{'1'} ||
$hash{$a}{'1'} cmp $hash{$b}{'2'}
} keys %hash;

print "$_ => $hash{ $_}\n" for @ordered_keys;

Anno
 
F

Frank

Well, you *can't* sort a hash, so the lack of success is no surprise.
Hash entries have no defined order.


Your sort block looks fine, but it is nonsense to assign the list of
hash keys to another hash. You don't even know if there's an even or
odd number of elements in it.

Try this (untested):

my @ordered_keys = sort {
$hash{$a}{'1'} cmp $hash{$b}{'1'} ||
$hash{$a}{'1'} cmp $hash{$b}{'2'}
} keys %hash;

print "$_ => $hash{ $_}\n" for @ordered_keys;

Anno

Now it works fine ^O^
Assigning the list to an hash instead of an array was not very smart :p


thanks,

Frank
 
F

Frank

Michele said:
Incidentally, I also think you may want the underlined 1 above to be a
2.

Yup I did, typed too fast from the script I use it in. But that wasn't
really the problem because I've changed that part of the script several
times in attempt to let it work ;)
 
A

anno4000

Frank said:
Yup I did, typed too fast from the script I use it in.

Don't re-type code, copy/paste it from a working script.
But that wasn't
really the problem because I've changed that part of the script several
times in attempt to let it work ;)

It may not be *your* problem but you make it a lot harder for us to
understand what you're trying to do. Debugging code is hard. Debugging
code that may not be the real code is near impossible.

Anno
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,769
Messages
2,569,578
Members
45,052
Latest member
LucyCarper

Latest Threads

Top