laziness, impatience, and hubris 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?
 [ambrus]: Also, I was wrong, apparently you have to support both periodic and one-shot timers in an AnyEvent backend [Corion]: ambrus: That looks deceptively simple, but maybe that's simply all that's needed. Which would be great! I hope I get to test it tomorrow, thanks!! [choroba]: Hm, unrelated question. [ambrus]: I added a timer implementation to ambrus's scratchpad as well, again the whole thing is completely untested and probably has more bugs than lines [choroba]: Anyone using anything to validate json contents of a REST service? [moritz]: choroba in python I use jsonschema [moritz]: I'm sure there's a Perl implementation of it too [choroba]: it seems Kelp and similar help you a lot with dispatching, but how to do something similar with contents? [moritz]: like JSON::Schema [Corion]: ambrus++ # more bugs than lines

How do I use this? | Other CB clients
Other Users?
Others examining the Monastery: (13)
As of 2016-12-08 12:46 GMT
Sections?
Information?
Find Nodes?
Leftovers?
Voting Booth?
On a regular basis, I'm most likely to spy upon:

Results (141 votes). Check out past polls.