#!/usr/bin/perl
use warnings; use strict;
# First, build the data structure.
# I took the liberty of making this a standalone test-case so I can run it.
our $shows_str = shows_str();
our @showtab;
for (split /^/, $shows_str) {
/\S/ or next;
/\A\s*(\S.*?)\s*\(([^()]+)\)/ or
die "error parseing input line ($_)";
my %s = (
name => $1,
user => $2,
);
push @showtab, \%s;
}
####
# 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 shows'),
!($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|Musicians)/),
!($s->{user} eq 'Lady_Aleena' && $s->{name} =~ /(Horror|Science fiction)/),
!($s->{user} eq 'Lady_Aleena' && $s->{name} eq 'Ripley\'s & Guinness'),
!($s->{user} eq 'LadyAleena_home'),
!($s->{user} eq 'Lady_Aleena' && $s->{name} =~ /(Followers' businesses|List subscribers)/),
);
my $k = join "", map { $_ ? "1" : "0" } @k;
$$s{sortflag} = $k;
}
for my $s (@showtab) {
show_sortflags($s);
}
####
# Depending on what my_sort does, you might also want to transform it
# in a similar way, to generate a key you can compare easily later,
# such as storing the show title with the article stripped off,
# casefolded. As I don't know what it does, I'll just use this stub
# and leave that as a homework to the reader.
sub my_sort {
my($a, $b) = @_;
$a cmp $b;
}
####
# 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;
####
# Print the results. I print the keys I've generated for
# debugging, you normally wouldn't print those.
print q{
,-----------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 'Premium TV shows'),
| ,--------D !($s->{user} eq 'LadyAleena_TV' && $s->{name} eq 'TV shows'),
| | E !($s->{user} eq 'LadyAleena_TV' && $s->{name} eq 'TV networks'),
| | F !($s->{user} eq 'Lady_Aleena' && $s->{name} =~ /(Comedians|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} =~ /(Followers' ...)/),
v v v v
ABCDEFGHIJ
};
for my $s (@showtab_sorted) {
print $$s{sortflag}, " ", $$s{name}, " (", $$s{user}, ")\n";
}
# The sample input
sub shows_str {
q{
Doctor Who (LadyAleena_TV)
Hercules & Xena (LadyAleena_TV)
Highlander (LadyAleena_TV)
Star Trek (LadyAleena_TV)
Leverage (LadyAleena_TNT)
Body of Proof (LadyAleena_ABC)
In Plain Sight (LadyAleena_USA)
Necessary Roughness (LadyAleena_USA)
seaQuest (LadyAleena_NBC)
Sanctuary (LadyAleena_SyFy)
Fairly Legal (LadyAleena_USA)
White Collar (LadyAleena_USA)
MythBusters (LadyAleena_TV)
Painkiller Jane (LadyAleena_SyFy)
Jericho (LadyAleena_CBS)
Harry's Law (LadyAleena_NBC)
Chuck (LadyAleena_NBC)
Grimm (LadyAleena_NBC)
Once Upon a Time (LadyAleena_ABC)
Primeval (LadyAleena_TV)
Stargate (LadyAleena_SyFy)
Eureka Warehouse13 Alphas (LadyAleena_SyFy)
No Ordinary Family (LadyAleena_ABC)
Buffy & Angel (LadyAleena_TV)
Covert Affairs (LadyAleena_USA)
Studio 60 (LadyAleena_NBC)
Buck Rogers 25th Century (LadyAleena_NBC)
Lipstick Jungle (LadyAleena_NBC)
Crossing Jordan (LadyAleena_NBC)
Law & Order (LadyAleena_NBC)
Firefly (LadyAleena_FOX)
Advtr of Brisco County Jr (LadyAleena_FOX)
Babylon 5 (LadyAleena_TV)
Haven (LadyAleena_SyFy)
Falling Skies (LadyAleena_TNT)
Bones & The Finder (LadyAleena_FOX)
The Mercury Men (LadyAleena_SyFy)
Andromeda (LadyAleena_SyFy)
Burn Notice (LadyAleena_USA)
Castle (LadyAleena_ABC)
Numb3rs (LadyAleena_CBS)
Rizzoli & Isles (LadyAleena_TNT)
ER Third Watch Med Invgtn (LadyAleena_NBC)
NBC TV shows (LadyAleena_NBC)
USA TV shows (LadyAleena_USA)
ABC TV shows (LadyAleena_ABC)
TNT TV shows (LadyAleena_TNT)
CBS TV shows (LadyAleena_CBS)
FOX TV shows (LadyAleena_FOX)
Premium TV shows (LadyAleena_TV)
TV shows (LadyAleena_TV)
TV networks (LadyAleena_TV)
Musicians (Lady_Aleena)
Comedians (Lady_Aleena)
Science fiction (Lady_Aleena)
Horror (Lady_Aleena)
Ripley's & Guinness (Lady_Aleena)
Utilities (LadyAleena_home)
Groceries (LadyAleena_home)
Software (LadyAleena_home)
Stores (LadyAleena_home)
List subscribers (Lady_Aleena)
Followers' businesses (Lady_Aleena)
}
};
__END__
####
,-----------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 'Premium TV shows'),
| ,--------D !($s->{user} eq 'LadyAleena_TV' && $s->{name} eq 'TV shows'),
| | E !($s->{user} eq 'LadyAleena_TV' && $s->{name} eq 'TV networks'),
| | F !($s->{user} eq 'Lady_Aleena' && $s->{name} =~ /(Comedians|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} =~ /(Followers' ...)/),
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)