No, you are right and I am wrong!
If the data you need for sorting is there in front of you with no need for any "mangling", the "straightforward sort block" is simpler to write than the Schwartzian Transform. I was confusing the tranforming done as a performance measure with other transformations to the data that are necessary because it is not yet in a sortable form.
If you do need to change the data in some way before the sort can take place then the Schwartzian Transform starts to gain in the straighforwardness factor, I think. The sort block method gains in readability because you can use meaningful variable names rather than $_; the Schwartzian Transform gains because the flow seems to me to be more obvious, albeit up the page which is counter-intuitive if you are used to piping commands in the shell. I tend to comment what is going on in the transform for those that are not familiar although I haven't below.
The examples I give here sort the output of df -k by controller, target, device and slice. First, the "straightforward sort block".
open DF, "df -k |" or die "$!\n";
print scalar <DF>;
while(<DF>)
{
next unless m{^/dev/dsk/c(\d+)t(\d+)d(\d+)s(\d+)};
push @lines, [$_, $1, $2, $3, $4];
}
close DF;
@sorted = sort {
$a->[1] <=> $b->[1] ||
$a->[2] <=> $b->[2] ||
$a->[3] <=> $b->[3] ||
$a->[4] <=> $b->[4]}
@lines;
print $_->[0] for @sorted;
Now the Schwartzian Transform.
open DF, "df -k |" or die "$!\n";
print scalar <DF>;
print
map {$_->[0]}
sort {
$a->[1] <=> $b->[1] ||
$a->[2] <=> $b->[2] ||
$a->[3] <=> $b->[3] ||
$a->[4] <=> $b->[4]
}
grep {defined $_->[1]}
map {[
$_,
m{^/dev/dsk/c(\d+)t(\d+)d(\d+)s(\d+)}
]}
<DF>;
close DF;
I think there are arguments in favour of either method. I have got used to Schwartian Transforms so I automatically reach for those when sorting problems come up.Cheers, JohnGG |