NSNumberFormatter和'th''st''nd''rd'(序数)数字结尾

jan*_*jan 31 objective-c nsnumberformatter ios

有没有办法使用NSNumberFormatter获得'th''st''nd''rd'数字结尾?

编辑:

看起来它不存在.这就是我正在使用的.

+(NSString*)ordinalNumberFormat:(NSInteger)num{
    NSString *ending;

    int ones = num % 10;
    int tens = floor(num / 10);
    tens = tens % 10;
    if(tens == 1){
        ending = @"th";
    }else {
        switch (ones) {
            case 1:
                ending = @"st";
                break;
            case 2:
                ending = @"nd";
                break;
            case 3:
                ending = @"rd";
                break;
            default:
                ending = @"th";
                break;
        }
    }
    return [NSString stringWithFormat:@"%d%@", num, ending];
}
Run Code Online (Sandbox Code Playgroud)

改编自nickf的答案这里 是否有一种简单的方法可以获得数字的"st","nd","rd"和"th"结尾?

Chr*_*let 37

从iOS 9开始,正确的方法是:

NSNumberFormatter *numberFormatter = [[NSNumberFormatter alloc] init];
numberFormatter.numberStyle = NSNumberFormatterOrdinalStyle;

NSLog(@"%@", [numberFormatter stringFromNumber:@(1)]); // 1st
NSLog(@"%@", [numberFormatter stringFromNumber:@(2)]); // 2nd
NSLog(@"%@", [numberFormatter stringFromNumber:@(3)]); // 3rd, etc.
Run Code Online (Sandbox Code Playgroud)

或者:

NSLog(@"%@", [NSString localizedStringFromNumber:@(1)
                                     numberStyle:NSNumberFormatterOrdinalStyle]); // 1st
Run Code Online (Sandbox Code Playgroud)

  • 从(我认为)iOS 4开始,还有`NumberFormatter.localizedString(from:n,number:.ordinal)`. (7认同)

小智 22

这可以用一种方法(英语).感谢nickf /sf/answers/4849911/在PHP中的原始代码,我只是将其改编为objective C: -

-(NSString *) addSuffixToNumber:(int) number
{
    NSString *suffix;
    int ones = number % 10;
    int tens = (number/10) % 10;

    if (tens ==1) {
        suffix = @"th";
    } else if (ones ==1){
        suffix = @"st";
    } else if (ones ==2){
        suffix = @"nd";
    } else if (ones ==3){
        suffix = @"rd";
    } else {
        suffix = @"th";
    }

    NSString * completeAsString = [NSString stringWithFormat:@"%d%@", number, suffix];
    return completeAsString;
}
Run Code Online (Sandbox Code Playgroud)


Gre*_*sek 16

其他Swift解决方案不会产生正确的结果并包含错误.我已将CmKndy解决方案翻译成Swift

extension Int {

    var ordinal: String {
        var suffix: String
        let ones: Int = self % 10
        let tens: Int = (self/10) % 10
        if tens == 1 {
            suffix = "th"
        } else if ones == 1 {
            suffix = "st"
        } else if ones == 2 {
            suffix = "nd"
        } else if ones == 3 {
            suffix = "rd"
        } else {
            suffix = "th"
        }
        return "\(self)\(suffix)"
    }

}
Run Code Online (Sandbox Code Playgroud)

测试结果:0th 1st 2nd 3rd 4th 5th 6th 7th 8th 9th 10th 11th 12th 13th 14th 15th 17th 18th 19th 20th 21th 22th 23rd


Abi*_*ern 14

由于这个问题需要一个格式化程序,这是我做的一个粗略的.

//
//  OrdinalNumberFormatter.h
//

#import <Foundation/Foundation.h>


@interface OrdinalNumberFormatter : NSNumberFormatter {

}

@end
Run Code Online (Sandbox Code Playgroud)

和实施:

//
//  OrdinalNumberFormatter.m
//

#import "OrdinalNumberFormatter.h"


@implementation OrdinalNumberFormatter

- (BOOL)getObjectValue:(id *)anObject forString:(NSString *)string errorDescription:(NSString **)error {
    NSInteger integerNumber;
    NSScanner *scanner;
    BOOL isSuccessful = NO;
    NSCharacterSet *letters = [NSCharacterSet letterCharacterSet];

    scanner = [NSScanner scannerWithString:string];
    [scanner setCaseSensitive:NO];
    [scanner setCharactersToBeSkipped:letters];

    if ([scanner scanInteger:&integerNumber]){
        isSuccessful = YES;
        if (anObject) {
            *anObject = [NSNumber numberWithInteger:integerNumber];
        }
    } else {
        if (error) {
            *error = [NSString stringWithFormat:@"Unable to create number from %@", string];
        }
    }

    return isSuccessful;
}

- (NSString *)stringForObjectValue:(id)anObject {
    if (![anObject isKindOfClass:[NSNumber class]]) {
        return nil;
    }

    NSString *strRep = [anObject stringValue];
    NSString *lastDigit = [strRep substringFromIndex:([strRep length]-1)];

    NSString *ordinal;


    if ([strRep isEqualToString:@"11"] || [strRep isEqualToString:@"12"] || [strRep isEqualToString:@"13"]) {
        ordinal = @"th";
    } else if ([lastDigit isEqualToString:@"1"]) {
        ordinal = @"st";
    } else if ([lastDigit isEqualToString:@"2"]) {
        ordinal = @"nd";
    } else if ([lastDigit isEqualToString:@"3"]) {
        ordinal = @"rd";
    } else {
        ordinal = @"th";
    }

    return [NSString stringWithFormat:@"%@%@", strRep, ordinal];
}

@end
Run Code Online (Sandbox Code Playgroud)

将其实例化为Interface Builder对象,并将Text Field的格式化程序出口附加到其中.为了更好地控制(例如设置最大值和最小值,您应该创建格式化程序的实例,根据需要设置属性,并使用它的setFormatter:方法将其附加到文本字段.

您可以从GitHub下载该类(包括示例项目)


Mag*_*goo 13

截至iOS 9

斯威夫特4

private var ordinalFormatter: NumberFormatter = {
    let formatter = NumberFormatter()
    formatter.numberStyle = .ordinal
    return formatter
}()

extension Int {
    var ordinal: String? {
        return ordinalFormatter.string(from: NSNumber(value: self))
    }
}
Run Code Online (Sandbox Code Playgroud)

最好将格式化程序放在扩展名之外......


sup*_*org 6

用英语很简单.这是一个快速扩展:

extension Int {
    var ordinal: String {
        get {
            var suffix = "th"
            switch self % 10 {
                case 1:
                    suffix = "st"
                case 2:
                    suffix = "nd"
                case 3:
                    suffix = "rd"
                default: ()
            }
            if 10 < (self % 100) && (self % 100) < 20 {
                suffix = "th"
            }
            return String(self) + suffix
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

然后打电话给:

    cell.label_position.text = (path.row + 1).ordinal
Run Code Online (Sandbox Code Playgroud)


Kru*_*tel 6

-迅捷4-

     let num = 1
     let formatter = NumberFormatter()
     formatter.numberStyle = .ordinal
     let day = formatter.string(from: NSNumber(value: num))

     print(day!)
     result - 1st
Run Code Online (Sandbox Code Playgroud)


jpi*_*man 5

只需添加另一个实现作为类方法.直到我从php中的一个例子实现了这个问题后才发现这个问题.

+ (NSString *)buildRankString:(NSNumber *)rank
{
    NSString *suffix = nil;
    int rankInt = [rank intValue];
    int ones = rankInt % 10;
    int tens = floor(rankInt / 10);
    tens = tens % 10;
    if (tens == 1) {
        suffix = @"th";
    } else {
        switch (ones) {
            case 1 : suffix = @"st"; break;
            case 2 : suffix = @"nd"; break;
            case 3 : suffix = @"rd"; break;
            default : suffix = @"th";
        }
    }
    NSString *rankString = [NSString stringWithFormat:@"%@%@", rank, suffix];
    return rankString;
}
Run Code Online (Sandbox Code Playgroud)


max*_*lov 5

这是一个适用于所有整数类型的紧凑Swift扩展:

extension IntegerType {
    func ordinalString() -> String {
        switch self % 10 {
        case 1...3 where 11...13 ~= self % 100: return "\(self)" + "th"
        case 1:    return "\(self)" + "st"
        case 2:    return "\(self)" + "nd"
        case 3:    return "\(self)" + "rd"
        default:   return "\(self)" + "th"
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

用法示例:

let numbers = (0...30).map { $0.ordinalString() }
print(numbers.joinWithSeparator(", "))
Run Code Online (Sandbox Code Playgroud)

输出:

第0,第1,第2,第3,第4,第5,第6,第7,第8,第9,第10,第11,第12,第13,第14,第15,第16,第17,第18,第19,第20,第21,第22,第23,第24, 25,26,27,28,29,30

  • 〜=是一个内置模式匹配运算符,在这种情况下,它检查`self%100`是否落在`[11 ... 13]`范围内,以正确处理"十分之一"情况.有关详细信息,请参阅:https://developer.apple.com/library/ios/documentation/Swift/Conceptual/Swift_Programming_Language/Patterns.html (2认同)

ymu*_*tlu 5

对此有一个简单的解决方案

迅速

let formatter = NumberFormatter()
formatter.numberStyle = .ordinal
let first = formatter.string(from: 1) // 1st
let second = formatter.string(from: 2) // 2nd
Run Code Online (Sandbox Code Playgroud)

对象-c

NSNumberFormatter *numberFormatter = [NSNumberFormatter new];
numberFormatter.numberStyle = NSNumberFormatterOrdinalStyle;
NSString* first = [numberFormatter stringFromNumber:@(1)]; // 1st
NSString* second = [numberFormatter stringFromNumber:@(2)]; // 2nd
Run Code Online (Sandbox Code Playgroud)

参考:hackingwithswift.com