snippet tye Schwartzian transform sort map stable <p> I was building sort keys such that a simple strcmp()/memcmp() could be used as the comparison function in a complex sort even before I found Perl (which was just before Perl 4 was released). </p><p> It turns out that this technique is very handy in Perl because it usually makes for the fastest possible sort by avoiding specifying a comparison function: <code> my @sorted= map { RESTORE($_) } sort map { XFORM($_) } @list; </code> </p><p> The main problem with the technique is that you need to build the key (XFORM) in such a way that the original record can be reconstructed from it (RESTORE). </p><p> That often makes this technique difficult to use, making it more of a specialized technique, not something you'd feel you could use all the time. </p><p> I'd previously used techniques that avoid this RESTORE() step but they still weren't general enough or elegant enough to be <b>the one</b> way to sort for me. </p><p> I finally [id://287131|came up with] a technique that I suspect will be "the one way to sort" for me (below). </p><p> It also has the feature that it produces a "stable" sort, that is, records with identical keys are kept in their original order relative to each other. </p> <code> sub XFORM { # Extract the sort key from $_[0] and return it. # This will often be written in-line # rather than as a real subroutine. } my @sorted= @list[ map { unpack "N", substr($_,-4) } sort map { XFORM($list[$_]) . pack "N", $_ } 0..$#list ]; </code><p> If you want to sort parallel lists, then you'd keep the sorted list of indices around: </p><code> my @index= map { unpack "N", substr($_,-4) } sort map { XFORM($name[$_]) . pack "N", $_ } 0..$#name; @name= @name[@index]; @data= @data[@index]; </code>