Do you know where your variables are? PerlMonks

Sorting Alphanumeric Arrays

by slloyd (Hermit)
 on Jun 13, 2005 at 19:59 UTC Need Help??
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
I do not see how this helps... :(

http://www.basgetti.com
Could it be that you're not actually following the links provided? There are a ton of suggestions in here, one of them is pointing to Sort::Naturally - which is probably the easiest and most generic way of solving your problem

slloyd,
How many of the methods did you try in the 3 minutes between my reply and yours?
```my @old = qw(99B 99 99A 100A 100 101 88);
my %data;
foreach my \$data (  @old  ) {
( my \$sort= \$data ) =~ s/(0*)(\d+)/
pack("C",length(\$2)) . \$1 . \$2 /ge;
\$data{\$sort}= \$data;
}
print "\$data{\$_}\n" for sort keys %data;

Cheers - L~R

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;

It's only merit (if any), relative to the other solutions posted, is that it illustrates a relatively general approach to this type of problem. It's most useful when the extraction of the parameter(s) to sort by (in this case, the job done by the parse sub) is costly.

the lowliest monk

Re: Sorting Alphanumeric Arrays
by gam3 (Curate) on Jun 13, 2005 at 20:10 UTC
You might want to look at the tread 442237. It has a lot on this, as well as a very good answer by tye.
-- gam3
A picture is worth a thousand words, but takes 200K.
Thanks Joost....use Sort::Versions works gr8..Thanks a ton

Create A New User
Node Status?
node history
Node Type: perlquestion [id://466268]
Approved by Joost
help
Chatterbox?
and all is quiet...

How do I use this? | Other CB clients
Other Users?
Others meditating upon the Monastery: (5)
As of 2017-12-13 00:50 GMT
Sections?
Information?
Find Nodes?
Leftovers?
Voting Booth?
What programming language do you hate the most?

Results (342 votes). Check out past polls.

Notices?