<?xml version="1.0" encoding="windows-1252"?>
<node id="358966" title="graff's scratchpad" created="2004-06-01 21:42:54" updated="2005-08-11 10:27:07">
<type id="182711">
scratchpad</type>
<author id="44715">
graff</author>
<data>
<field name="doctext">
&lt;c&gt;
@sorted = map { s/^\S+ // }
          sort
          map { 
              my ( $x ) = ( /^_(\S+)/ ) ? ( $1 ) : ( /(\S+)$/ );
              "$x $_"
              }  @unsorted; 
&lt;/c&gt;
Explanation (going upwards from the bottom, which is how it works):
&lt;ol&gt;
&lt;li&gt; The first map block (the one on the bottom) creates a lexically scoped variable $x, and assigns a single non-whitespace token (string) to it.  The value of $x depends on whether $_ (the current string from @unprocessed that map is handling) begins with "_".  If it does, $x gets the first token of the line (minus the "_"), otherwise, it gets the last token.
&lt;li&gt; Each iteration of the first map outputs the string "$x $_"
&lt;li&gt; The sort works in the normal way, working on the modified list of strings
&lt;li&gt; The second map block (at the top) reprocesses the sorted list of strings, by undoing the work of the first one, by removing the initial token from each item.
&lt;/ol&gt;
&lt;P&gt;
An adaptation of a code snippet from [pad://LadyAleena]:
&lt;c&gt;
    elsif ($type =~ /name/) {
        for ( $c, $d ) {
            my $x = ( /^_(.*)/ ) ? $1 : substr( $_, rindex( $_, ' ' ));
            $_ = "$x $_";
        }
        return $c cmp $d;
    }
&lt;/c&gt;</field>
</data>
</node>
