Elijah has asked for the wisdom of the Perl Monks concerning the following question:
Does anyone know of an effective sort method? One that will list 12 after 1 instead of before?
my %hash = (
1 => [1, One],
2 => [2, Two],
3 => [3, Three],
4 => [4, Four],
5 => [5, Five],
6 => [6, Six],
12 => [12, Twelve],
);
my @sort;
for my $key (keys %hash) {
push @sort, "$hash{$key}[0]::$hash{$key}[1]";
}
for (sort @sort) {
my ($int, $alpha) = split(/::/, $_);
print "Integer is: $int -- Alpha is: $alpha\n";
}
This will display:
Integer is: 12 -- Alpha is: Twelve
Integer is: 1 -- Alpha is: One
Integer is: 2 -- Alpha is: Two
Integer is: 3 -- Alpha is: Three
Integer is: 4 -- Alpha is: Four
Integer is: 5 -- Alpha is: Five
Integer is: 6 -- Alpha is: Six
Re: Effective sort method?
by bobf (Monsignor) on Jan 03, 2006 at 06:33 UTC
|
As mentioned in the chatterbox, you wanted to sort by the first element of the array rather than by the hash key. This example will work:
use strict;
use warnings;
my %hash = (
1 => [1, 'One'],
2 => [2, 'Two'],
3 => [3, 'Three'],
4 => [4, 'Four'],
5 => [5, 'Five'],
6 => [6, 'Six'],
12 => [12, 'Twelve'],
);
# sort the hash numerically by the first element in each array
foreach my $key ( sort { $hash{$a}[0] <=> $hash{$b}[0] } keys %hash )
{
print "Integer is: $key -- Alpha is: $hash{$key}[1]\n";
}
Please also note that if you had warnings turned on you would have realized the second element in your arrays are barewords and need to be quoted.
Relevant links:
| [reply] [Watch: Dir/Any] [d/l] |
Re: Effective sort method?
by simonm (Vicar) on Jan 03, 2006 at 06:25 UTC
|
sort { $a <=> $b } @sort
| [reply] [Watch: Dir/Any] [d/l] |
Re: Effective sort method?
by l.frankline (Hermit) on Jan 03, 2006 at 06:40 UTC
|
my %hash = (
1 => [1, One],
2 => [2, Two],
3 => [3, Three],
4 => [4, Four],
5 => [5, Five],
6 => [6, Six],
12 => [12, Twelve],
);
my @sort;
for my $key (sort (keys %hash)) {
push @sort, "$hash{$key}[0]::$hash{$key}[1]";
}
my @new = sort { $a <=> $b } @sort;
for (@new) {
my ($int, $alpha) = split(/::/, $_);
print "Integer is: $int -- Alpha is: $alpha\n";
}
regards, Franklin
Don't put off till tomorrow, what you can do today.
| [reply] [Watch: Dir/Any] [d/l] |
Re: Effective sort method?
by superfrink (Curate) on Jan 03, 2006 at 06:50 UTC
|
Here is how I did it. I changed the keys in the original hash to strings so there was no confusion over sorting the keys vs sorting the first element of the array.
#!/usr/bin/perl -w
use strict;
use Data::Dumper;
my %hash = (
'a' => [1, 'One'],
'b' => [2, 'Two'],
'c' => [3, 'Three'],
'd' => [4, 'Four'],
'e' => [5, 'Five'],
'f' => [6, 'Six'],
'g' => [12, 'Twelve'],
);
my %key_ht;
foreach my $key (keys %hash) { $key_ht{$hash{$key}[0]} = $key }
# print "key_ht:", Dumper(\%key_ht), "\n";
foreach my $key (sort { $a <=> $b } keys %key_ht) {
my $num = $hash{$key_ht{$key}}[0];
my $str = $hash{$key_ht{$key}}[1];
print "Integer is: ", $num, " -- Alpha is: ", $str, "\n";
}
Update: the output I get is:
Integer is: 1 -- Alpha is: One
Integer is: 2 -- Alpha is: Two
Integer is: 3 -- Alpha is: Three
Integer is: 4 -- Alpha is: Four
Integer is: 5 -- Alpha is: Five
Integer is: 6 -- Alpha is: Six
Integer is: 12 -- Alpha is: Twelve
| [reply] [Watch: Dir/Any] [d/l] [select] |
Re: Effective sort method?
by planetscape (Chancellor) on Jan 03, 2006 at 13:05 UTC
|
| [reply] [Watch: Dir/Any] |
|
I also recommend "A Fresh Look at Efficient Perl Sorting" by Uri Guttman and Larry Rosler.
http://www.sysarch.com/perl/sort_paper.html
It talks about performance but I found it interesting because it explains different samples of sorting code.
| [reply] [Watch: Dir/Any] |
Re: Effective sort method?
by smokemachine (Hermit) on Jan 03, 2006 at 17:48 UTC
|
#!/usr/bin/perl
$\="\n";
my %hash = (
1 => "One",
2 => "Two",
3 => "Three",
4 => "Four",
5 => "Five",
6 => "Six",
12 => "Twelve",
);
print "Integer is: $_ -- Alpha is: $hash{$_}" for (sort {$a <=> $b}
+ keys %hash)
| [reply] [Watch: Dir/Any] [d/l] |
|
|