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

This probably is a very simple sort question. I want to sort data like
d3 d1 d10 d2 d20 d21 d100 d201
so that I get
d1
d2
d3
d10
d20
d21
d100
d201
If the data is in an array then
foreach $t_item (sort {$a cmp $b} @t1) {
does not give what I want.
What is the simplest way of doing this?

Replies are listed 'Best First'.
Re: Simple sort query
by Perlbotics (Archbishop) on Apr 24, 2010 at 08:28 UTC

    Hi. Seems that you need to sort first by alpha-prefix and then numerically. The suggestion below assumes that all items to be sorted have a format that matches m/(\D+)(\d+)/ completely.
    See also What is "Schwarzian Transform" (aka Schwartzian) and Schwartzian Transform

    use strict; my @input = qw(d3 d1 d10 d2 d20 d21 a3 d100 d201 a10 a1); my @sorted = map { $_->[0] . $_->[1] } # 3) put together elems. sort { $a->[0] cmp $b->[0] # 2) sort alpha prefix || # (if equal, then) $a->[1] <=> $b->[1] } # sort numeric suffix map { m/(\D+)(\d+)/; [ $1, $2 ] } # 1) split alpa/numeric-parts @input; print join "\n", @sorted, "\n"; __END__ a1 a3 a10 d1 d2 d3 d10 d20 d21 d100 d201
Re: Simple sort query
by salva (Canon) on Apr 24, 2010 at 09:36 UTC
    If your data matches /^d(\d+)$/:
    @sorted = sort { substr($a, 1) <=> substr($b, 1) } @data
    If your data matches /^(\D+)(\d+)$/:
    use Sort::Key::Multi qw(si_keysort); # "si" indicates that the sorting keys # are a string and an integer my @sorted = si_keysort { /^(\D*)(\d*)$/ } @data;
      This is really a reply to all who kindly and helpfully answered.
      How can this be extended when there is a variable number of alpha characters before any numeric ones?
        The solution provided by Perlbotics extends to values where there is at least a non-numeric character followed by at least a numeric character.

        You can change it to something else by changing the regular expression (and the anonymous subroutine provided to sort, if required).

Re: Simple sort query
by Cody Fendant (Hermit) on Apr 24, 2010 at 09:01 UTC