You are using a Schwartzian Transform which is good. In this example my expensive function splits the name into three parts (word chars, digits or ., and then everything else). split is a good way to do it as 1) if it fails it will return the whole string (so we can sort on that). If it succeeds then we need to remember that it will split at all the number . sequences so we put the string back together after the first split. If we were to use a straight regex here and it failed to match we would need to have all sorts of fallback cases split() handles it neatly.
The sort then proceeds on first bit, numbers, last bit. If you just wanted to sort foo-bar-0.01.tar.gz then you only need to return @bits[0,1] from func() for it to work correctly.
sub sort_n {
return
map { $_->[0] }
sort { $a->[1] cmp $b->[1] || $a->[2] <=> $b->[2] || $a->[3] cmp $b-
+>[3] }
map { [$_, func($_)] } @_;
sub func { my @bits = split /([\d\.]+)/, $_[0]; return @bits[0,1], j
+oin '', @bits[2..$#bits] }
}
my @ary = qw( z1z z2a z2z a1a a2b a1.1a a2.1a a0.1a a0.01a b bbb b2b2b
+2b 2b2c a2bc2 );
print "This is what func() does for us\n";
$" = ', ';
for (@ary) { my @a = func($_); print "@a\n" }
print "\nHere is the sorted list\n";
print "$_\n" for sort_n(@ary);
__DATA__
This is what func() does for
z, 1, z
z, 2, a
z, 2, z
a, 1, a
a, 2, b
a, 1.1, a
a, 2.1, a
a, 0.1, a
a, 0.01, a
b, ,
bbb, ,
b, 2, b2b2b
, 2, b2c
a, 2, bc2
Here is the sorted list
2b2c
a0.01a
a0.1a
a1a
a1.1a
a2b
a2bc2
a2.1a
b
b2b2b2b
bbb
z1z
z2a
z2z
cheers
tachyon
s&&rsenoyhcatreve&&&s&n.+t&"$'$`$\"$\&"&ee&&y&srve&&d&&print
-
Are you posting in the right place? Check out Where do I post X? to know for sure.
-
Posts may use any of the Perl Monks Approved HTML tags. Currently these include the following:
<code> <a> <b> <big>
<blockquote> <br /> <dd>
<dl> <dt> <em> <font>
<h1> <h2> <h3> <h4>
<h5> <h6> <hr /> <i>
<li> <nbsp> <ol> <p>
<small> <strike> <strong>
<sub> <sup> <table>
<td> <th> <tr> <tt>
<u> <ul>
-
Snippets of code should be wrapped in
<code> tags not
<pre> tags. In fact, <pre>
tags should generally be avoided. If they must
be used, extreme care should be
taken to ensure that their contents do not
have long lines (<70 chars), in order to prevent
horizontal scrolling (and possible janitor
intervention).
-
Want more info? How to link
or How to display code and escape characters
are good places to start.