Complex13:
You may have seen a bubble sort, it goes something like this:
my @vars = (7, 12, 49, 44);
sub bubble_sort {
for my $i (1 .. $#vars) {
for my $j (0 .. $i-1) {
print "vars[$i]=$vars[i], vars[$j]=$vars[j]: ";
if ($vars[i]<$vars[j]) {
print "vars[$i]<vars[$j], swapping!\n";
my $t=$vars[i]; $vars[$i]=$vars[$j]; $vars[$j]=$t;
}
else {
print "vars[$i]>=vars[$j], no swap needed.\n";
}
}
}
}
I put in print statements to help you see how it would work. There are many different sorting algorithms, but this one is pretty easy to read and understand. As you can see, the sort simply compares elements in the list and swaps them depending on their order. The bubble sort above should sort from the lowest value to the highest value. But if you wanted to sort in the other direction, you'd need to change the if statement. Also, if you wanted to sort different types of items, you'd need to change the if statement.
So what they did was to let you provide your own comparison function, so you can sort any items you want in any order. If we do that to our bubble sort, and take out the print statements, it could look like this:
my @vars = (7, 12, 49, 44);
sub bubble_sort {
my $rfunc = shift;
for my $i (1 .. $#vars) {
for my $j (0 .. $i-1) {
if (&($rfunc)($vars[i], $vars[j])) {
my $t=$vars[i]; $vars[$i]=$vars[$j]; $vars[$j]=$t;
}
}
}
}
So for the updated bubble_sort, we have to pass it a function that will return true if we want it to swap the elements in the list, and false if they don't need to be swapped. So we can sort in ascending order like this:
sub ascending {
my ($left, $right) = @_;
return $right > $left;
}
bubble_sort(\ascending);
You get the picture. But you don't always want to clutter your program with a zillion trivial functions that you use only once. It will clutter your namespace (oops--I can't call that function ascending, I've already used it for something else!). So rather than creating a function by name, we can create an anonymous subroutine, and pass that to our bubble sort:
bubble_sort(sub { my ($left, $right)=@_; return $right>$left });
That's a lot better, right? Well in perl you don't even have to pass an anonymous subroutine. Perl lets you pass references to code, too, which gets you the rest of the way to the built-in sort function.
It's late here, so I glossed over quite a few things. I'm sure perl doesn't use the bubble sort, but that's just a detail. I didn't worry about passing the list to be sorted, as I didn't want to clutter up the coded with the details of the extra parameters and such. But I hope it's complete enough to get the point across. Finally, I didn't run any of this code, either, so it may have an error or two.
Let me know if it's clear enough, I'll be glad to give further details if I left anything out that you needed.
...roboticus
When your only tool is a hammer, all problems look like your thumb.
Update: As Khen1950x mentions below, the sort built-in expects a comparison function that returns -1, 0, or +1. I got away with true/false because the bubble sort didn't need any further information. But some more advanced sorting algorithms need/want a little more information. |