Re: Sort hash keys
by VincentK (Beadle) on Mar 18, 2014 at 18:16 UTC
|
use strict;
use warnings;
use Sort::Naturally;
my %DATA_HASH =
(
'hs1' => 1,
'hs2' => 1,
'hs3' => 1,
'hs10' => 1,
'hs9' => 1,
'hs15' => 1,
'hs21' => 1,
'hs110' => 1,
'hs11' => 1
);
print "$_\n" foreach nsort keys %DATA_HASH;
__END__
Output:
C:\monks\sort>perl test_sort.pl
hs1
hs2
hs3
hs9
hs10
hs11
hs15
hs21
hs110
C:\monks\sort>
| [reply] [d/l] |
|
FYI, there seem to be a couple bugs related to floats, negative integers, and text/number combos.
| [reply] |
Re: Sort hash keys
by kennethk (Abbot) on Mar 18, 2014 at 17:20 UTC
|
So, your issue is that you have a number preceded by alphabetic characters, and you want to do numeric sorting on the numbers? In your sample, all your keys begin with hs. Is this guaranteed? Also, what is this %planets hash? Essentially, if you want to sort based on a substring of your key, then you will need to parse out that substring.
The easiest answer here would probably be to keep leading 0's on your keys, e.g. hs01 instead of hs1. Barring that, you could do the parsing in a named sub:
use strict;
my %planets;
my %cuantas_veces_sale;
for my $nombre (sort keysort keys %cuantas_veces_sale) {
print "$nombre\n";
};
sub keysort {
return $planets{$a} <=> $planets{$b} if $planets{$a} <=> $planets{
+$b};
my ($num_a) = $a =~ /(\d+)/;
my ($num_b) = $b =~ /(\d+)/;
$num_a <=> $num_b;
}
or possibly cache the parse in a hash ahead of time:
use strict;
my %planets;
my %cuantas_veces_sale;
my %alphas = map {$_ => /(\D+)/} keys %cuantas_veces_sale;
my %numerics = map {$_ => /(\d+)/} keys %cuantas_veces_sale;
for my $nombre (sort { $planets{$a} <=> $planets{$b}
or $alphas{$a} cmp $alphas{$b}
or $numerics{$a} cmp $numerics{$b} } keys %cuant
+as_veces_sale) {
print "$nombre\n";
};
#11929 First ask yourself `How would I do this without a computer?' Then have the computer do it the same way.
| [reply] [d/l] [select] |
|
I updated the code, the planets things was just a test and i copy the wrong code.
Yes hs is always there, and i can't put hs01 or whatever it must be hs1, hs2 and so on
| [reply] |
Re: Sort hash keys
by Eily (Monsignor) on Mar 18, 2014 at 17:25 UTC
|
cmp uses alphabetical order, you want numerical order on the number alone. One simple solution would be to have a function to extract the number out of the key and do :
@sortedKeys = sort { $planets{$a} <=> $planets{$b} or getNum($a) <=> getNum($b) } keys %cuantas_veces_sale;
This not the most effective solution, but it works well enough. To get the number inside the string you can use a regex like /(\d+)/, tr/// or substr depending on what you find the easier. The last two are perhaps more user-friendly, but require that your keys have a consistant format ("hs" and then the number for exemple).
| [reply] [d/l] [select] |
Re: Sort hash keys
by LanX (Saint) on Mar 18, 2014 at 17:13 UTC
|
I suppose you want
for my $nombre (sort { $a cmp $b or $planets{$a} <=> $planets{$b} } keys %cuantas_veces_sale)
Though you haven't been clear what %planet holds.
Cheers Rolf
( addicted to the Perl Programming Language)
| [reply] [d/l] |
|
| [reply] |
|
DB<106> sort {$a <=> $b } @keys
=> (
"hs5",
"hs6",
"hs7",
"hs8",
"hs9",
"hs10",
"hs11",
"hs12",
"hs13",
"hs14",
"hs15",
)
Cheers Rolf
( addicted to the Perl Programming Language)
| [reply] [d/l] |
|
|