in reply to A new golf challenge - Natural Sorting

Not truly golfed; more of a canonical solution:

sub _nsc { my( $x, @a ) = @{$_[0]}; my( $y, @b ) = @{$_[1]}; @a && @b ? ( $x =~ /\d/ ? ( $y =~ /\d/ ? $x <=> $y || _nsc(\@a,\@b) : -1 ) : ( $y =~ /\d/ ? 1 : lc($x) cmp lc($y) || _nsc(\@a,\@b) )) : ( @a ? 1 : @b ? -1 : 0 ) } sub natsort { map join('',@$_), sort {_nsc($a,$b)} map [/(\d+|\D+)/g], @_ }
We're building the house of the future together.

Replies are listed 'Best First'.
Re^2: A new golf challenge - Natural Sorting
by jdporter (Paladin) on Mar 17, 2006 at 14:44 UTC

    Wups - there's a bug in that version of _nsc. Here's a better one:

    sub _nsc { my @a = @{$_[0]}; my @b = @{$_[1]}; @a && @b or return( @a ? 1 : @b ? -1 : 0 ); my $x = shift @a; my $y = shift @b; $x =~ /\d/ ? ( $y =~ /\d/ ? length($x)<=>length($y) || $x <=> $y || _nsc(\@a,\@b) : -1 ) : ( $y =~ /\d/ ? 1 : lc($x) cmp lc($y) || _nsc(\@a,\@b) ) }

    (This version also optimizes to only compare numeric strings as numbers iff they have the same length.)

    We're building the house of the future together.
Re^2: A new golf challenge - Natural Sorting
by ikegami (Patriarch) on Mar 17, 2006 at 14:44 UTC
    Forget golf, it doesn't even work. <=> will fail for 865314457646576532325988.
      Which means that a solution more robust than <=> will have to compare numbers using arbitrary precision (and that just pushes the threshold a few orders of magnitude farther out). Which means that numbers will have to be recognized as such, so that -123.4e-45.6E789 would not be taken as a single number, but -123.4e-456 will be. And then we get into whether whitespace, underscores, and commas/decimals (depending on locale) are allowed, and what they mean.

      It's a long tee shot, onto a glacier, and only transparent golf balls are available.

      -QM
      --
      Quantum Mechanics: The dreams stuff is made of

      Ouch. ;-)