in reply to Sorting Numbers & Text
It's not as easy as it used to be... and actually it never worked all that well. We've always had to deal with the problem of "Rabbit" being sorted above "apple" because of case issues (that could be dealt with by normalizing the case inside of the sort routine, and then falling back to case-sensitive sorting in case of equality). And we've always had the issue of string comparisons of numbers numerically incorrectly. But now we also have to worry about Unicode issues.
Additionally, you do want numbers to be sorted numerically, and alpha characters to be sorted alphabetically, I believe. I think that most dictionary style sorts put numbers ahead of alpha characters as well (you seemed to be looking for the opposite, but I'll ignore that for a moment).
Here's one way to do it that should be Unicode safe:
use strict; use warnings; use utf8; use Unicode::Collate::Locale; use Scalar::Util 'looks_like_number'; use feature qw/say unicode_strings/; binmode STDOUT, ':utf8'; my @unsorted = qw( 041351920234 Rabbit 0343120 041271024500 000000343119 0430870 Apple 041460301399 ); my $collator = Unicode::Collate::Locale->new(locale => 'en'); my @sorted = sort { ( looks_like_number($a) && looks_like_number($b) && $a <=> $b ) || $collator->getSortKey($a) cmp $collator->getSortKey($b) } @unsorted; say for @sorted;
Pretty ugly, and still falls back to alphabetical sorting when a given string has non-numeric characters embedded within it.
I'd love for someone to come along and show a better way to do it, as this just seems messy.
Dave
|
|---|