Simple and Complex List Sorting
#!/usr/bin/perl -w
############################## Sorting Lists ###############################
@list = (2,1,21,3);
@list = sort @list;
print "@list\n"; # Produces 1 2 21 3 because default is ASCII sort.
@list = sort by_num @list;
print "@list\n";
@list = sort {$b <=> $a} @list; # Do one-line sort subs this way!!
print "@list\n";
@list = sort {$b cmp $a} @list;
print "@list\n";
sub by_num
{
$a <=> $b; # Must use $a and $b. The <=> is NUMERIC comparison.
} # Sort subs must return +1, 0, or -1. Thus, <=> or
# cmp are generally in the final expression.
$var = "abc12xyzjlk*340dfdf10";
@list = reverse $var =~ /\d+/g; # List functions work on anything
# which creates a list, not just on
# list variables!
print "@list\n";
########################## Program Output Below #########################
1 2 21 3 # ASCIIbetical order.
1 2 3 21 # Numeric order -- sub by_num called.
21 3 2 1 # Descending numeric order -- sub by_num_descending.
3 21 2 1 # Descending ASCIIbetical order. By_ASCII_descending called.
5 4 3 2 1 # Reversal of (1,2,3,4,5) list.
10 340 12 # Grabs 12 340 10 out of the chaotic scalar and then
# submits this list to the reverse function.
#!/usr/bin/perl -w
######################### Complex Sort Demo ############################
@list = ("Williams,Jim 34 40000.00 2\n", # Demo of secondary and
"Clinton,Hillary 34 80000.00 2\n", # tertiary keys.
"Discussion,Frank 45 66555.00 4\n",
"Doubt,Flip 34 70000.00 3\n",
"Jones,Jenny 34 80000.00 4\n");
@list = sort by_age_then_salary_then_deps @list;
print @list;
sub by_age_then_salary_then_deps
{
($ageA, $salaryA, $depsA) = (split /\s+/, $a) [1..3];
($ageB, $salaryB, $depsB) = (split /\s+/, $b) [1..3];
$ageA <=> $ageB
or
$salaryA <=> $salaryB # Use salary to break tie in ages.
or
$depsA <=> $depsB; # Use number of dependents to break tie
} # in ages.
######################### Output of Above Sort ############################
Williams,Jim 34 40000.00 2 # Secondary and tertiary keys worked!!
Doubt,Flip 34 70000.00 3
Clinton,Hillary 34 80000.00 2
Jones,Jenny 34 80000.00 4
Discussion,Frank 45 66555.00 4
#############################################################################
#### Sorting Strings by the Sum of the ASCII Values of Their Characters ####
@list = qw(goofy foobar xxxxxx john perl);
foreach $string (@list) # Calculate sums by hand for correctnes proof
{
$sum = 0;
foreach $char (split //, $string)
{
$sum += ord($char); # Ord gives ASCII value of $char.
}
print "Sum for $string: $sum\n";
}
# See if we can sort by sum of ordinal
# values of characters in strings.
foreach $element (sort by_sum_of_chars @list)
{
print "$element\n";
}
sub by_sum_of_chars
{
my ($sum1, $sum2, $char);
$sum1 = $sum2 = 0;
foreach $char (split //,$a)
{
$sum1 += ord($char);
}
foreach $char (split //, $b)
{
$sum2 += ord($char);
}
$sum1 <=> $sum2;
}
############################# Output Below #############################
Sum for goofy: 548 # Calculations of sum of ord(chars).
Sum for foobar: 633
Sum for xxxxxx: 720
Sum for john: 431
Sum for perl: 435
john # Sort by the sum of ord(chars) -- it worked!!
perl
goofy
foobar
xxxxxx
######################## Sorting a File By Date #########################
#!/usr/bin/perl -w
open(IN, "calendar") or die "Cannot open calendar!\n";
open(OUT,">calendar.out") or die "Cannot open calendar.out!\n";
@sorted_dates = sort by_date <IN>;
print OUT @sorted_dates;
sub by_date
{
my ($monA, $monB, $dayA, $dayB, $yearA, $yearB, $sortdateA, $sortdateB);
($monA, $dayA, $yearA) = $a =~ m|^(\d\d?)/(\d\d?)/(\d{4})|;
($monB, $dayB, $yearB) = $b =~ m|^(\d\d?)/(\d\d?)/(\d{4})|;
$sortdateA = sprintf "%4d%02d%02d", $yearA, $monA, $dayA;
$sortdateB = sprintf "%4d%02d%02d", $yearB, $monB, $dayB;
$sortdateA cmp $sortdateB;
}
########################### Sort-by-Date Results #########################
calendar:
5/24/1997 - Trip to Cincinnati.
11/27/1997 - Thanksgiving Dinner.
12/23/1997 - Christmas party.
3/25/1998 - Easter Dinner.
3/26/1998 - Go to ballroom dance.
4/9/1998 - Meet with financial advisor.
4/17/1998 - Funeral for Bozo the Clown.
4/17/1998 - Doctor's appointment.
4/17/1998 - Fed Ex package to Joe.
5/4/1998 - Dentist appointment.
Calendar.out:
5/24/1997 - Trip to Cincinnati.
11/27/1997 - Thanksgiving Dinner.
12/23/1997 - Christmas party.
3/25/1998 - Easter Dinner.
3/26/1998 - Go to ballroom dance.
4/9/1998 - Meet with financial advisor.
4/17/1998 - Doctor's appointment.
4/17/1998 - Fed Ex package to Joe.
4/17/1998 - Funeral for Bozo the Clown.
5/4/1998 - Dentist appointment.
######################## Sorting Hashes by Value #########################
#!/usr/bin/perl -w
%capitols = create_capitols_hash();
foreach $state (sort {$capitols{$a} cmp $capitols{$b}} keys %capitols)
{
print "$state: $capitols{$state}\n";
}
sub create_capitols_hash
{
my ($state, $capitol, %capitols);
open(STATES, "states") or die "Cannot open states file!\n";
while (<STATES>) # Loop uses $_ defaults all the way through!
{
chomp;
($state, $capitol) = split(/:/);
$capitols{$state} = $capitol;
}
return %capitols;
}
############################ Hash Sort Result ##############################
California:Sacramento # Original file.
North Dakota:Bismarck
Pennsylvania:Harrisburg
Nevada:Carson City
Arizona:Phoenix
Louisiana:Baton Rouge
South Dakota:Pierre
Nebraska:Lincoln
Iowa:Des Moines
Illinois:Springfield
Florida:Tallahassee
Alabama:Montgomery
Mississippi:Jackson
Oregon:Salem
Washington:Olympia
Idaho:Boise
Louisiana: Baton Rouge # Sorted by capitol (values of %capitols).
North Dakota: Bismarck
Idaho: Boise
Nevada: Carson City
Iowa: Des Moines
Pennsylvania: Harrisburg
Mississippi: Jackson
Nebraska: Lincoln
Alabama: Montgomery
Washington: Olympia
Arizona: Phoenix
South Dakota: Pierre
California: Sacramento
Oregon: Salem
Illinois: Springfield
Florida: Tallahassee