in reply to A new golf challenge - Natural Sorting

I'm not really interested in Perl Golf, hence this late reply, but I'd like to contribute by stating my favourite approach for natural sorting, that apparently nobody has touched in this thread. The basis is this:
split /(\d+)/
This will split the example strings like this:
1
"", 1
A
"A"
amstelveen
"amstelveen"
Amsterdam
"Amsterdam"
Amsterdam5
"Amsterdam", 5
Amsterdam40
"Amsterdam", 40
Amsterdam40b
"Amsterdam", 40, "b"
Amsterdamned
"Amsterdamned"
and now for some more complex examples:
Chapter 1 Section 3
"Chapter ", 1, "Section ", 3
Chapter 1 Section 10
"Chapter ", 1, "Section ", 10

Now the basic trick to do natural sorting, is partwise comparison of the items, comparing the even numbered items (starting at 0) with alphabetical comparison, case insensitive even if you like, and the odd numbered items with numerical comparison.

This is code that does basically that:

sub natcomp { my @a = split /(\d+)/, $a; my @b = split /(\d+)/, $b; my $last = min(scalar @a, scalar @b)-1; my $cmp; for my $i (0 .. $last) { unless($i & 1) { # even $cmp = lc $a[$i] cmp lc $b[$i] || $a[$i] cmp $b[$i] and re +turn $cmp; }else { # odd $cmp = $a[$i] <=> $b[$i] and return $cmp; } } return scalar @a <=> scalar @b; # shortest array comes first }

Let's try this with:

chomp(my @array = <DATA>); $\ = "\n"; print for sort natcomp @array; __DATA__ 1 A amstelveen Amsterdam Amsterdam40 Amsterdam40b Amsterdam5 Amsterdamned Chapter 1 Section 10 Chapter 1 Section 3 Chapter 10 Section 2 Chapter 2 Section 1
(Note that the DATA section is sorted alphabetically, and that it contains an empty string)

The result is:


1
A
amstelveen
Amsterdam
Amsterdam5
Amsterdam40
Amsterdam40b
Amsterdamned
Chapter 1 Section 3
Chapter 1 Section 10
Chapter 2 Section 1
Chapter 10 Section 2

I hope that order is to your liking.