in reply to Re^6: top ten things every Perl hacker should know
in thread top ten things every Perl hacker should know

You can look at Re^5: top ten things every Perl hacker should know for an example of the same sort written as a Schwartzian Transform and as a regular sort. (I intentionally chose one that was similar to the example that gave the Schwartzian transform its name.)
  • Comment on Re^7: top ten things every Perl hacker should know

Replies are listed 'Best First'.
Re^8: top ten things every Perl hacker should know
by johngg (Canon) on Mar 18, 2006 at 12:07 UTC
    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