in reply to Converting ordinal numbers to words prior to sorting
Sifmole is right that Number::Spell will get you part of the way, but unfortunately it doesn't handle ordinals at all.
My first thought was that you could just add a new set of mappings:
1 => 'first', 2 => 'second', ... 12 => 'twelfth', ... 30 => 'thirtieth', ...
And use those ones if the supplied digit includes one of those distinctive suffixes. But it doesn't quite work: you'd end up with 'thirtieth first' for '31st'. Making it treat the first digit of 30 differently to the same digit in 31 is actually kind of painful.
But then it occurred to me that it's easier just to post-process the output of Number::Spell for those cases where you know it's an ordinal rather than a numeral. The word-ending translation is actually fairly regular, as these things go. Here's a first attempt:
use Number::Spell; my %ord = ( one => 'first', two => 'second', three => 'third', four => 'fourth', five => 'fifth', six => 'sixth', en => 'enth', eight => 'eighth', nine => 'ninth', twelve => 'twelfth', ty => 'tieth', hundred => 'hundredth', thousand => 'thousandth', ion => 'ionth' ); my @list = qw(1st 11th 3rd 13th 83rd 11 33 1 15 1000000th); my @stringlist; foreach my $number (@list) { my $stringversion; if ($number =~ m/(\d+)(?:st|th|rd)$/i) { $stringversion = spell_number($1); $stringversion =~ s/($_)$/$ord{$_}/i for keys %ord; } else { $stringversion = spell_number($number); } push @stringlist,$stringversion; } print join(', ',@stringlist);
Which prints:
first, eleventh, third, thirteenth, eighty third, eleven, thirty three, one, fifteen, one millionth
It's not very pretty, nor is it economical (it doesn't exit that for loop after a match, for example), but you get the idea. I believe this works for any figure that Number::Spell can handle, but i'm sure there's an exception somewhere that i haven't thought of.
|
|---|