in reply to Sorting on Section Numbers
my @a = qw/1 2 2.2 2.13 2.1.7 3.4a 10.4a.3b.8/; my @sortables = map { [grep /[^\.]/, split/([\.a-z])/, $_] } @a; print join "\n", map join(' ', @{$_}), @sortables;
Your sort then just needs to have a function which splits up the entries and compares them.
my @list = qw/1 10.4a.3b.8 2.2 2 2.13 3.4a 2.1.7 /; print join "\n", sort compare @list; sub compare { my @a = grep /[^\.]/, split/([\.a-z])/, $a; my @b = grep /[^\.]/, split/([\.a-z])/, $b; { my ($c, $d) = (shift @a, shift @b); (!defined $c and defined $d) and return -1; ( defined $c and !defined $d) and return 1; (!defined $c and !defined $d) and return 0; ($c > $d) and return 1; ($c < $d) and return -1; redo; } }
You should avoid repeatedly splitting the lists by caching the split results.
There may be an error stuck somewhere in here; my test set was just what is in the above code. Hope this works for you.my @list = qw/1 10.4a.3b.8 2.2 2 2.13 3.4a 2.1.7 /; my @cache = map { [grep /[^\.]/, split/([\.a-z])/, $_] } @list; print join("\n", map("@$_", sort compare @cache)); sub compare { my @a = @$a; my @b = @$b; { my ($c, $d) = (shift @a, shift @b); (!defined $c and defined $d) and return -1; ( defined $c and !defined $d) and return 1; (!defined $c and !defined $d) and return 0; ($c > $d) and return 1; ($c < $d) and return -1; redo; } }
|
---|