# Write a function to precompute all those boolean keys you want to
# sort by. This should be an improvement because now the code has
# each condition only once, not twice, so we reduced code duplication.
# The key is just a string of "0" and "1" characters. For simplicity,
# we store the key right into the record.
our @networks = qw(ABC CBS FOX NBC SyFy TNT USA);
our $network_string = join('|',@networks);
sub show_sortflags {
my($s) = @_;
my @k;
push @k, (
!($s->{user} =~ /LadyAleena_($network_string|TV)/ && $s->{name
+} !~ /TV/),
!($s->{user} =~ /LadyAleena_($network_string)/ && $s->{name} =
+~ /TV shows$/),
!($s->{user} eq 'LadyAleena_TV' && $s->{name} eq 'Premium TV s
+hows'),
!($s->{user} eq 'LadyAleena_TV' && $s->{name} eq 'TV shows'),
!($s->{user} eq 'LadyAleena_TV' && $s->{name} eq 'TV networks'
+),
!($s->{user} eq 'Lady_Aleena' && $s->{name} =~ /(Comedians|Mus
+icians)/),
!($s->{user} eq 'Lady_Aleena' && $s->{name} =~ /(Horror|Scienc
+e fiction)/),
!($s->{user} eq 'Lady_Aleena' && $s->{name} eq 'Ripley\'s & Gu
+inness'),
!($s->{user} eq 'LadyAleena_home'),
!($s->{user} eq 'Lady_Aleena' && $s->{name} =~ /(Followers' bu
+sinesses|List subscribers)/),
);
my $k = join "", map { $_ ? "1" : "0" } @k;
$$s{sortflag} = $k;
}
for my $s (@showtab) {
show_sortflags($s);
}
# Now do the sort relying on the key we computed. Note that as
# the compare function is still non-trivial, I don't write its
# body in the same line as the sort, because that's ugly.
sub show_compare {
my($a, $b) = @_;
return $$a{sortflag} cmp $$b{sortflag} ||
my_sort($$a{name}, $$b{name}, "article");
}
our @showtab_sorted = sort { show_compare($a, $b) } @showtab;
Output:
,-----------A !($s->{user} =~ /LadyAleena_($network_string|TV)/ && $s
+->{name} !~ /TV/),
| B !($s->{user} =~ /LadyAleena_($network_string)/ && $s->{
+name} =~ /TV shows$/),
| C !($s->{user} eq 'LadyAleena_TV' && $s->{name} eq 'Premi
+um TV shows'),
| ,--------D !($s->{user} eq 'LadyAleena_TV' && $s->{name} eq 'TV sh
+ows'),
| | E !($s->{user} eq 'LadyAleena_TV' && $s->{name} eq 'TV ne
+tworks'),
| | F !($s->{user} eq 'Lady_Aleena' && $s->{name} =~ /(Comedi
+ans|Musicians)/),
| | ,-----G !($s->{user} eq 'Lady_Aleena' && $s->{name} =~ /(Horror
+|Science fiction)/),
| | | H !($s->{user} eq 'Lady_Aleena' && $s->{name} eq 'Ripley\
+'s & Guinness'),
| | | I !($s->{user} eq 'LadyAleena_home'),
| | | ,--J !($s->{user} eq 'Lady_Aleena' && $s->{name} =~ /(Follow
+ers' ...)/),
v v v v
ABCDEFGHIJ
0111111111 Advtr of Brisco County Jr (LadyAleena_FOX)
0111111111 Andromeda (LadyAleena_SyFy)
0111111111 Babylon 5 (LadyAleena_TV)
0111111111 Body of Proof (LadyAleena_ABC)
0111111111 Bones & The Finder (LadyAleena_FOX)
0111111111 Buck Rogers 25th Century (LadyAleena_NBC)
0111111111 Buffy & Angel (LadyAleena_TV)
0111111111 Burn Notice (LadyAleena_USA)
0111111111 Castle (LadyAleena_ABC)
0111111111 Chuck (LadyAleena_NBC)
0111111111 Covert Affairs (LadyAleena_USA)
0111111111 Crossing Jordan (LadyAleena_NBC)
0111111111 Doctor Who (LadyAleena_TV)
0111111111 ER Third Watch Med Invgtn (LadyAleena_NBC)
0111111111 Eureka Warehouse13 Alphas (LadyAleena_SyFy)
0111111111 Fairly Legal (LadyAleena_USA)
0111111111 Falling Skies (LadyAleena_TNT)
0111111111 Firefly (LadyAleena_FOX)
0111111111 Grimm (LadyAleena_NBC)
0111111111 Harry's Law (LadyAleena_NBC)
0111111111 Haven (LadyAleena_SyFy)
0111111111 Hercules & Xena (LadyAleena_TV)
0111111111 Highlander (LadyAleena_TV)
0111111111 In Plain Sight (LadyAleena_USA)
0111111111 Jericho (LadyAleena_CBS)
0111111111 Law & Order (LadyAleena_NBC)
0111111111 Leverage (LadyAleena_TNT)
0111111111 Lipstick Jungle (LadyAleena_NBC)
0111111111 MythBusters (LadyAleena_TV)
0111111111 Necessary Roughness (LadyAleena_USA)
0111111111 No Ordinary Family (LadyAleena_ABC)
0111111111 Numb3rs (LadyAleena_CBS)
0111111111 Once Upon a Time (LadyAleena_ABC)
0111111111 Painkiller Jane (LadyAleena_SyFy)
0111111111 Primeval (LadyAleena_TV)
0111111111 Rizzoli & Isles (LadyAleena_TNT)
0111111111 Sanctuary (LadyAleena_SyFy)
0111111111 Star Trek (LadyAleena_TV)
0111111111 Stargate (LadyAleena_SyFy)
0111111111 Studio 60 (LadyAleena_NBC)
0111111111 The Mercury Men (LadyAleena_SyFy)
0111111111 White Collar (LadyAleena_USA)
0111111111 seaQuest (LadyAleena_NBC)
1011111111 ABC TV shows (LadyAleena_ABC)
1011111111 CBS TV shows (LadyAleena_CBS)
1011111111 FOX TV shows (LadyAleena_FOX)
1011111111 NBC TV shows (LadyAleena_NBC)
1011111111 TNT TV shows (LadyAleena_TNT)
1011111111 USA TV shows (LadyAleena_USA)
1101111111 Premium TV shows (LadyAleena_TV)
1110111111 TV shows (LadyAleena_TV)
1111011111 TV networks (LadyAleena_TV)
1111101111 Comedians (Lady_Aleena)
1111101111 Musicians (Lady_Aleena)
1111110111 Horror (Lady_Aleena)
1111110111 Science fiction (Lady_Aleena)
1111111011 Ripley's & Guinness (Lady_Aleena)
1111111101 Groceries (LadyAleena_home)
1111111101 Software (LadyAleena_home)
1111111101 Stores (LadyAleena_home)
1111111101 Utilities (LadyAleena_home)
1111111110 Followers' businesses (Lady_Aleena)
1111111110 List subscribers (Lady_Aleena)
Update: some random nodes with sorts (in case you want to find keywords to search for) are Schwartzian Transform, Schwartzian Transform, Benchmark, -s versus schwartzian, Sorting an array of arrays by field, Re: Spiraling integers. I think none of these really tell about sorting using multiple keys, some boolean and some textual though.
Update: However, the Sort::Key CPAN module does seem to offer a way to sort using multiple keys of different types, so check that out. It might be the easiest solution.
Update: removed use 5.014; – I think all of that should work fine in older perls too. But people, come on, can't you upgrade yet?
|