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