slloyd has asked for the wisdom of the Perl Monks concerning the following question:

Either I am brain dead or this is tougher than meets the eye. I have the following array:
```my @old=("99B","99","99A","100A","100","101","88");
I want to sort it so that the output is as follows:
```88
99
99A
99B
100
100A
101
How would I go about doing this? Thanks

http://www.basgetti.com

Replies are listed 'Best First'.
Re: Sorting Alphanumeric Arrays
by ikegami (Pope) on Jun 13, 2005 at 20:05 UTC

Sort numerically, but switch to alphabetical for ties:

```@new = sort { no warnings; \$a <=> \$b || \$a cmp \$b } @old;
Thank you! perfect!

http://www.basgetti.com
Re: Sorting Alphanumeric Arrays
by Limbic~Region (Chancellor) on Jun 13, 2005 at 20:03 UTC
A reply falls below the community's threshold of quality. You may see it by logging in.
Re: Sorting Alphanumeric Arrays
by Joost (Canon) on Jun 13, 2005 at 20:05 UTC
use Sort::Versions
```#!/usr/local/bin/perl -w
use strict;
use Sort::Versions;

my @old = ("99B","99","99A","100A","100","101","88");

print "\$_\n" for sort { versioncmp(\$a,\$b) } @old;
output:
```88
99
99A
99B
100
100A
101

Re: Sorting Alphanumeric Arrays
by BrowserUk (Pope) on Jun 13, 2005 at 20:06 UTC
```my @old=("99B","99","99A","100A","100","101","88");
print sort{ \$^W=0; \$a <=> \$b or \$a cmp \$b } @old;
88 99 99A 99B 100 100A 101

Of course, you can tart that up with a GRT or ST for efficiency if the size of your dataset warrents it.

Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
Lingua non convalesco, consenesco et abolesco. -- Rule 1 has a caveat! -- Who broke the cabal?
"Science is about questioning the status quo. Questioning authority".
The "good enough" maybe good enough for the now, and perfection maybe unobtainable, but that should not preclude us from striving for perfection, when time, circumstance or desire allow.
GRT or ST are not the fastest ways to sort in perl anymore:
```use Sort::Key::Maker sort_int_str =>
sub { int \$_, \$_ }, qw(int str);

my @sorted = sort_int_str @old;

updated: using a regular expresion like /(\d+)(.*)/ to extract the keys was slow!

GRT or ST are not the fastest ways to sort in perl anymore:

Bold claim, but in my tests a simple sort wins from 10 to 1000+ data items, with a GRT taking over from 10,000 upto 1 million data items:

```P:\test>466286 -N=10
Rate S::M  GRT sort
S::M 15958/s   -- -22% -60%
GRT  20443/s  28%   -- -49%
sort 39790/s 149%  95%   --

P:\test>466286 -N=100
Rate S::M  GRT sort
S::M 1814/s   -- -17% -40%
GRT  2173/s  20%   -- -28%
sort 3024/s  67%  39%   --

P:\test>466286 -N=1000
Rate S::M  GRT sort
S::M 157/s   --  -5% -21%
GRT  166/s   6%   -- -17%
sort 200/s  27%  20%   --

P:\test>466286 -N=10000
Rate S::M sort  GRT
S::M 13.2/s   --  -2%  -3%
sort 13.5/s   2%   --  -0%
GRT  13.6/s   3%   0%   --

P:\test>466286 -N=100000
Rate sort S::M  GRT
sort 0.938/s   --  -7% -11%
S::M  1.01/s   7%   --  -4%
GRT   1.05/s  12%   4%   --

P:\test>466286 -N=1000000
(warning: too few iterations for a reliable count)

(warning: too few iterations for a reliable count)

(warning: too few iterations for a reliable count)

s/iter sort S::M  GRT
sort   13.8   --  -8% -22%
S::M   12.7   9%   -- -16%
GRT    10.7  29%  19%   --

Benchmark

Also, I got make test failures when building?

Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
Lingua non convalesco, consenesco et abolesco. -- Rule 1 has a caveat! -- Who broke the cabal?
"Science is about questioning the status quo. Questioning authority".
The "good enough" maybe good enough for the now, and perfection maybe unobtainable, but that should not preclude us from striving for perfection, when time, circumstance or desire allow.
Re: Sorting Alphanumeric Arrays
by tlm (Prior) on Jun 13, 2005 at 20:09 UTC

Here's one approach, using a Schwartzian Transform:

```sub parse {
my \$item = shift;
return [ \$item, \$item =~ /^(\d+)([a-zA-Z]*)/ ];
}

sub sort_alphanum {
\$a->[ 1 ] <=> \$b->[ 1 ] or
\$a->[ 2 ] cmp \$b->[ 2 ];
}

my @sorted =
map \$_->[ 0 ],
sort sort_alphanum
map parse( \$_ ), @old;