Sorting with the Schwartzian Transform
Randal L. Schwartz
It was a rainy April in Oregon more than a decade ago when I saw the Usenet
post made by Hugo Andrade Cartaxeiro on the now defunct comp.lang.perl
newsgroup:
I have a (big) string like that:
print $str;
eir 11 9 2 6 3 1 1 81% 63% 13
oos 10 6 4 3 3 0 4 60% 70% 25
hrh 10 6 4 5 1 2 2 60% 70% 15
spp 10 6 4 3 3 1 3 60% 60% 14
and I like to sort it with the last field as the order key. I know perl has some
features to do it, but I can't make 'em work properly.
In the middle of the night of that rainy April (well, I can't remember whether
it was rainy, but that's a likely bet in Oregon), I replied, rather briefly,
with the code snippet:
$str =
join "\n",
map { $_->[0] }
sort { $a->[1] <=> $b->[1] }
map { [$_, (split)[-1]] }
split /\n/,
$str;
And even labeled it "speaking Perl with a Lisp". As I posted that snippet, I had
no idea that this particular construct would be named and taught as part of idiomatic
Perl, for I had created the Schwartzian Transform. No, I didn't name it,
but in the follow-up post from fellow Perl author and trainer Tom Christiansen,
which began:
Oh for cryin' out loud, Randal! You expect a NEW PERL PROGRAMMER to make heads
or tails of THAT? :-) You're postings JAPHs for solutions, which isn't going
to help a lot. You'll probably manage to scare these poor people away from the
language forever? :-) BTW, you have a bug.
Tom eventually went on to describe what my code actually did. Oddly enough,
the final lines of that post end with:
I'm just submitting a sample chapter for his perusal for inclusion the mythical
Alpaca Book :-)
It would be another 8 years before I would finally write that book, making
it the only O'Reilly book whose cover animal was known that far in advance.
|