Schwartzian transform

Aaron Crane perl at
Wed Aug 13 12:17:48 BST 2014

Dermot <paikkos at> wrote:
> my $count = 1;
> my @sorted =
>     map { $ref->{ $_->[0] }->{position} = $count++; $ref->{ $_->[0] } }
>     sort { $a->[1] <=> $b->[1] }
>     map [ $_, $ref->{$_}->{position} ],
>     keys %{ $ref };

It's not clear to me that the Schwartzian Transform adds anything to
this code: with it, you have to create an array ref for every input
hash ref, and then sort by an element of each array ref, but without
it, you could simply sort by an element of each input hash ref:

my @sorted = sort { $a->{position} <=> $b->{position} } values %$ref;

I haven't measured the relative execution speed of this code and the
version using the Schwartzian Transform; I think the enormous increase
in clarity you get this way will outweigh any speed improvement you
might get from the ST. (If indeed there is any — since the key you're
sorting on is quick to calculate, it's not impossible that the extra
allocations needed for the ST will make it actually slower in

If you don't actually need to keep @sorted around, the whole thing can
be even simpler:

my $position = 1;
$_->{position} = $position++
    for sort { $a->{position} <=> $b->{position} } values %$ref;

I've also renamed your $count variable to $position, because I think
that more accurately reflects what it contains.

Aaron Crane **

More information about the mailing list