in reply to Sort problems

You could also try a Guttman Rosler transform. This melds the fields to sort and the whole item into a single string that can be sorted lexically. The original item can then be pulled from the sorted string afterwards. pack or sprintf are often used to construct the string. Care has to be taken to make sure the fields pack to a consistent length across all of the list to be sorted!

use strict; use warnings; my @list = qw{ a1_2 a1_1 a10_10 a2_10 a2_1 a2_2 a10_1 a10_2 a1_10 }; my @sorted = map { substr $_, 8 } sort map { pack q{NNa*}, m{(\d+)_(\d+)}, $_ } @list; print qq{$_\n} for @sorted;

The output.

a1_1 a1_2 a1_10 a2_1 a2_2 a2_10 a10_1 a10_2 a10_10

I hope this is of interest.

Cheers,

JohnGG

Replies are listed 'Best First'.
Re^2: Sort problems
by AnomalousMonk (Archbishop) on Dec 03, 2008 at 03:08 UTC
    pack q{NNa*}, m{(\d+)_(\d+)}, $_
    Note that packing with an 'N' specifier fails if either of the numeric fields exceeds 4294967295. An approach using sprintf (as mentioned in johngg's reply) can get around this.
    >perl -wMstrict -le "my @list = qw{ a1_2 a1_1 a10_10 a2_10 a2_1 a2_2 a10_1 a10_2 a1_10 }; use constant WIDTH => 20; my @sorted = map { substr $_, WIDTH * 2 } sort map { sprintf '%0*4$d%0*4$d%s', m{(\d+)_(\d+)}, $_, WIDTH } @list; print for @sorted; " a1_1 a1_2 a1_10 a2_1 a2_2 a2_10 a10_1 a10_2 a10_10

      Nice ++

      I had never seen the *4$ construct, used to grab arguments by position for printf/sprintf, before. Very useful. Thanks for pointing it out.

      Cheers,

      JohnGG

      Where can I find an explanation for the extra formatting details that resulted in '%0*4$d%0*4$d%s' (I'd like to learn more about this myself). Has such support been around for a long time in Perl? Is it Perl-specific, or does the GNU C library now support such syntax?