Is there a way in Objective-C to take a number and spell it out?

若如初见. 提交于 2020-01-12 21:56:30

问题


I'm looking for a way to take a number (say 5 or 207), spell it out, and returns its ordinal form as a string (five or two hundred seven). All I could find was code that takes a number and returns its ordinal suffix (st, nd, rd, th) and the parts of English grammar guides that say you should spell out ordinals.

I'm looking for a way to get a spelled out number with its ordinal suffix (fifth or two hundred seventh).


回答1:


Update: I came across this answer today, suggesting the use of the use of this library under the MIT-License which also supports a few other languages. Hope this helps someone.

Old Answer:
I coded a script which can this, but only in english:

- (NSString*)getSpelledOutNumber:(NSInteger)num
{
    NSNumber *yourNumber = [NSNumber numberWithInt:(int)num];
    NSNumberFormatter *formatter = [[NSNumberFormatter alloc] init];
    [formatter setNumberStyle:NSNumberFormatterSpellOutStyle];
    [formatter setLocale:[[NSLocale alloc] initWithLocaleIdentifier:@"en"]];
    return [formatter stringFromNumber:yourNumber];
}

- (NSString*)removeLastCharOfString:(NSString*)aString
{
    return [aString substringToIndex:[aString length]-1];
}

- (NSString*)getSpelledOutOrdinalNumber:(NSInteger)num
{    
    NSString *spelledOutNumber = [self getSpelledOutNumber:num];

    // replace all '-'
    spelledOutNumber = [spelledOutNumber stringByReplacingOccurrencesOfString:@"-"
                                                                   withString:@" "];

    NSArray *numberParts = [spelledOutNumber componentsSeparatedByString:@" "];

    NSMutableString *output = [NSMutableString string];

    NSUInteger numberOfParts = [numberParts count];
    for (int i=0; i<numberOfParts; i++) {
        NSString *numberPart = [numberParts objectAtIndex:i];

        if ([numberPart isEqualToString:@"one"])
            [output appendString:@"first"];
        else if([numberPart isEqualToString:@"two"])
            [output appendString:@"second"];
        else if([numberPart isEqualToString:@"three"])
            [output appendString:@"third"];
        else if([numberPart isEqualToString:@"five"])
            [output appendString:@"fifth"];
        else {
            NSUInteger characterCount = [numberPart length];
            unichar lastChar = [numberPart characterAtIndex:characterCount-1];
            if (lastChar == 'y')
            {
                // check if it is the last word
                if (numberOfParts-1 == i)
                { // it is
                    [output appendString:[NSString stringWithFormat:@"%@ieth ", [self removeLastCharOfString:numberPart]]];
                }
                else
                { // it isn't
                    [output appendString:[NSString stringWithFormat:@"%@-", numberPart]];
                }
            }
            else if (lastChar == 't' || lastChar == 'e')
            {
                [output appendString:[NSString stringWithFormat:@"%@th-", [self removeLastCharOfString:numberPart]]];
            }
            else
            {
                [output appendString:[NSString stringWithFormat:@"%@th ", numberPart]];
            }
        }
    }

    // eventually remove last char
    unichar lastChar = [output characterAtIndex:[output length]-1];
    if (lastChar == '-' || lastChar == ' ')
        return [self removeLastCharOfString:output];
    else
        return output;
}

The usage is pretty simple:

NSString *ordinalNumber = [self getSpelledOutOrdinalNumber:42];

The number would be 'forty-second'. I hope that helps you.




回答2:


This should have been accepted as the correct answer. NSNumberFormatter will do the job, and it's a standard approach, not some shaky workaround.

Here is an example:

NSNumberFormatter* numberFormatter = [[NSNumberFormatter alloc] init];
[numberFormatter setNumberStyle:NSNumberFormatterSpellOutStyle];
NSString* stringFromNumber = [numberFormatter stringFromNumber:your_number_goes_here];
NSLog( @"%@", stringFromNumber );

It will output 'one' for 1 'two' for 2 etc. Besides, it works perfectly for nonEnglish locales as well. For example, if you change the number formatter locale to German:

numberFormatter.locale = [NSLocale localeWithLocaleIdentifier:@"DE"];

the code above will print: 'eins' for 1 'zwei' for 2 and so on.




回答3:


I once wrote a tool called vpi2english. It is part of my vpi toolbox, written in matlab. But the code is pretty simple really, and could be converted to another language if you choose. It essentially takes a (decimal) digit string, breaks it down into pieces of three digits at a time, and writes them each in words.

>> vpi2english(vpi('2331546567543686356564321'))
ans =
   two septillion, three hundred thirty one sextillion,
five hundred forty six quintillion, five hundred sixty seven quadrillion,
five hundred forty three trillion, six hundred eighty six billion,
three hundred fifty six million, five hundred sixty four thousand,
three hundred twenty one 

It currently works on numbers as large as 1 less than 1e306, which is as large as I could find names for such numbers online.

>> vpi2english(999999*vpi(10)^300)
ans =
nine hundred ninety nine centillion, nine hundred ninety nine novemnonagintillion



回答4:


Short answer: NO

First of all this task doesn't belong to Objective-C as a programming language. Second, the result should depend on user locale.



来源:https://stackoverflow.com/questions/6716596/is-there-a-way-in-objective-c-to-take-a-number-and-spell-it-out

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!