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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/3312935/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-30 17:26:23  来源:igfitidea点击:

NSNumberFormatter and 'th' 'st' 'nd' 'rd' (ordinal) number endings

iosobjective-cnsnumberformatter

提问by jan

Is there a way to use NSNumberFormatter to get the 'th' 'st' 'nd' 'rd' number endings?

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

EDIT:

编辑:

Looks like it does not exist. Here's what I'm using.

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

+(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];
}

Adapted from nickf's answer here Is there an easy way in .NET to get "st", "nd", "rd" and "th" endings for numbers?

改编自 nickf's answer here 在 .NET 中是否有一种简单的方法可以获得数字的“st”、“nd”、“rd”和“th”结尾?

采纳答案by Abizern

Since the question asked for a number formatter, here's a rough one I made.

由于问题要求使用数字格式化程序,因此我做了一个粗略的。

//
//  OrdinalNumberFormatter.h
//

#import <Foundation/Foundation.h>


@interface OrdinalNumberFormatter : NSNumberFormatter {

}

@end

and the implementation:

和实施:

//
//  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

Instantiate this as an Interface Builder object and attach the Text Field's formatter outlet to it. For finer control (such as setting maximum and minimum values, you should create an instance of the formatter, set the properties as you wish and attach it to text field using it's setFormatter:method.

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

You can download the class from GitHub(including an example project)

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

回答by Chris Nolet

The correct way to do this from iOS 9 onwards, is:

从 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.

Alternatively:

或者:

NSLog(@"%@", [NSString localizedStringFromNumber:@(1)
                                     numberStyle:NSNumberFormatterOrdinalStyle]); // 1st

回答by CmKndy

This does the trick in one method (for English). Thanks nickf https://stackoverflow.com/a/69284/1208690for original code in PHP, I just adapted it to objective C:-

这是一种方法(对于英语)的技巧。感谢 nickf https://stackoverflow.com/a/69284/1208690提供 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;
}

回答by Magoo

As of iOS 9

从 iOS 9 开始

Swift 4

斯威夫特 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))
    }
}

It's probably best to have the formatter outside the extension...

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

回答by Greg Lukosek

Other Swift solutions do not produce correct result and contain mistakes. I have translated CmKndy solution to Swift

其他 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)"
    }

}

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

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

回答by Krunal Patel

-- Swift 4 --

-- 斯威夫特 4 --

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

     print(day!)
     result - 1st

回答by superarts.org

It's quite simple in English. Here's a swift extension:

这在英语中很简单。这是一个快速的扩展:

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
        }
    }
}

Then call something like:

然后调用类似的东西:

    cell.label_position.text = (path.row + 1).ordinal

回答by jpittman

Just adding another implementation as a class method. I didn't see this question posted until after I implemented this from an example in php.

只需添加另一个实现作为类方法。直到我从 php.ini 的示例中实现了这个问题之后,我才看到这个问题。

+ (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;
}

回答by maxkonovalov

Here's a compact Swift extension suitable for all integer types:

这是一个适用于所有整数类型的紧凑型 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"
        }
    }
}

Example usage:

用法示例:

let numbers = (0...30).map { 
let formatter = NumberFormatter()
formatter.numberStyle = .ordinal
let first = formatter.string(from: 1) // 1st
let second = formatter.string(from: 2) // 2nd
.ordinalString() } print(numbers.joinWithSeparator(", "))

Output:

输出:

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

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

回答by ymutlu

There is a simple solution for this

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

Swift

迅速

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

Obj-c

对象-c

##代码##

Referance: hackingwithswift.com

参考:hackingwithswift.com