Your bucketsort is the elegant solution that I was seeking. Interesting though it's about twice as slow as my ugly version as indicated by this benchmark:That's because you didn't fix my typos. Here's a different benchmark, with some of the other suggestions (I didn't include any that went beyond sorting on 'fld_type'):
#!/usr/bin/perl use strict; use warnings; use Benchmark qw /timethese cmpthese/; our @advocates = map {{fld_title => 'Rec' . $_, fld_type => [qw /National State Local/] -> [ra +nd 3]}} 1 .. shift || 1000; sub by_locale { my $a_type; my $b_type; $a_type = 1 if ($a->{'fld_type'} =~ /local/i); $a_type = 2 if ($a->{'fld_type'} =~ /state/i); $a_type = 3 if ($a->{'fld_type'} =~ /national/i); $b_type = 1 if ($b->{'fld_type'} =~ /local/i); $b_type = 2 if ($b->{'fld_type'} =~ /state/i); $b_type = 3 if ($b->{'fld_type'} =~ /national/i); $a_type <=> $b_type; } my $order = "\0local\0state\0national\0"; sub by_locale_b { index ($order, "\0" . lc ($a -> {fld_type}) . "\0") <=> index ($order, "\0" . lc ($b -> {fld_type}) . "\0") } our (@knowmad, @abigail, @borisz, @pirate); cmpthese -1 => { knowmad => '@knowmad = sort by_locale @advocates', abigail => 'my %bucket; map {push @{$bucket {$_ -> {fld_type}}} => $_} @advo +cates; @abigail = map {@{$bucket {$_}}} qw /Local State Nat +ional/;', borisz => 'my %h = (National => 3, State => 2, Local => 1); @borisz = sort {$h {$a -> {fld_type}} <=> $h {$b -> {fld_type}}} @advocates;', pirate => '@pirate = map {$_ -> [1]} sort {$a -> [0] <=> $b -> [0]} map {[lc ($_ -> {fld_type}), $_]} @advoca +tes', browseruk => '@browseruk = sort by_locale_b @advocates', }; __END__ Rate knowmad browseruk borisz pirate abigail knowmad 39.4/s -- -48% -70% -83% -92% browseruk 75.5/s 91% -- -42% -67% -85% borisz 130/s 229% 72% -- -43% -74% pirate 229/s 480% 203% 76% -- -53% abigail 491/s 1147% 551% 279% 115% --
Abigail
In reply to Re: Efficiently sorting array by non-alpha strings
by Abigail-II
in thread Efficiently sorting array by non-alpha strings
by knowmad
For: | Use: | ||
& | & | ||
< | < | ||
> | > | ||
[ | [ | ||
] | ] |