Update: I am replying to this part: I would still like to maybe understand what's happening w/$a and $b in cmp routines. I interpreted this to mean: how does comparison and $a and $b work? This is not directly on the point of the original question, but appears to be on point for the follow-up statement.
I'll try to help you with $a, $b and cmp. I've tried to explain this a
number of times - sometimes with more success than others! I have not
read by anybody or written myself the "perfect" faq on this - so this is
just yet another attempt! On a subject like this, I think that hearing
it from different people in different words helps. For that reason,
I'm not sure that it is even possible to write the "perfect" faq on this!
The reason for sorting is of course to order something. Order what? In order
to "sort" something, we have to start with "something" where order has meaning.
That sounds basic, but sometimes this is a stumbling block!
That "something" is a list of stuff or an array of stuff. This cannot be a
hash of stuff because hashes have no order (we can sort the keys to a hash
because we can make an ordered list of them), but to "sort the hash" itself has
no meaning, because a hash has no sequential order.
The basic syntax of Perl sort is:
@output = sort{...code block...}@input;
I'm going to back up and generalize a bit now... The following applies not
only to Perl, but to C, C++, Java, etc. Current computers (not quantum computers)
only deal with the comparison of 2 things at once. Fancy sorting algorithms deal with
how to minimize the total number of comparisons that are required
between 2 individual things to get the input data list into the desired order.
The language or sorting library will provide the "fancy sorting algorithm"
that minimizes the number of comparisons. What you have to provide is
a way for that sorting library or language
function to know
whether two things are: "a<b, exactly the same: a==b", or b>a".
Every language has its own way of implementing this requirement that
the user program provide a way of comparing two things. Perl has two
magic global variables, $a and $b. sort{...code block...}@input
causes pairs of things from @input to be set to $a and $b and then the code
within the sort block to be run. In Perl cmp causes an alphabetic comparison to be used. In Perl <=>, the "spaceship" operator causes numeric values to be used for the comparison.
Re: Sorting help illustrates a lot of these points.
Re: Custom sort with string of numbers gives more practical "how-to"
I hope the code below will lead you into a "Oh, my gosh!" realization! The code within the sort{...} block is essentially a subroutine and you can put other stuff in there like "print"! Below, I show which 2 items the version specific sort compares.
#!/usr/bin/perl -w
use strict;
my @array1 = ("jerry", "abe", "hope", "crazy_horse", "lewis","bob");
print "initial array order: @array1\n";
my @array = sort @array1;
print "The default sort: @array\n";
@array = sort{$a cmp $b}@array1;
print "The same sort order: @array\n\n";
@array = sort{
print "comparing $a and $b \n";
$a cmp $b;
} @array1;
print "\n";
print "The same thing: @array\n\n";
__END__
initial array order: jerry abe hope crazy_horse lewis bob
The default sort: abe bob crazy_horse hope jerry lewis
The same sort order: abe bob crazy_horse hope jerry lewis
comparing jerry and abe
comparing hope and crazy_horse
comparing lewis and bob
comparing abe and crazy_horse
comparing crazy_horse and jerry
comparing jerry and hope
comparing abe and bob
comparing bob and crazy_horse
comparing crazy_horse and lewis
comparing lewis and hope
comparing lewis and jerry
The same thing: abe bob crazy_horse hope jerry lewis
Update: One of the main points that I was trying to get across was that when you see a tricky, map{} grep{} sort{} and wonder what it does and how it works?, it is completely fine to put some print statements in there! I do this when I am debugging something complex and my brain can't comprehend why "what is happening" is happening! These code blocks that map, grep, sort use are like subroutines. Please note that the last statement in a block like what I'm talking about cannot be 'print "$result\n";' because "print" like all I/O routines returns a status, in this case '1', so you need something like: print $result; $result; or some other way so that the last line is the return value. |