NSNumberFormatter et 'e' 'e' 'nd' 'rd' (ordinale) nombre de terminaisons

y a-t-il un moyen d'utiliser NSNumberFormatter pour obtenir les terminaisons 'th' 'st' 'nd' rd 'number?

EDIT:

semble ne pas exister. Voici ce que j'utilise.

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

adapté de la réponse de nickf ici y a-t-il un moyen facile dans .NET pour obtenir "st", "nd", "rd" et "th" fin pour les nombres?

27
demandé sur Leo Dabus 2010-07-23 00:04:52

19 réponses

puisque la question demandait un formateurde nombre, voici un grossier que j'ai fait.

//
//  OrdinalNumberFormatter.h
//

#import <Foundation/Foundation.h>


@interface OrdinalNumberFormatter : NSNumberFormatter {

}

@end

et la mise en œuvre:

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

instanciez ceci comme un objet Interface Builder et attachez la sortie formatter du champ de texte à cet objet. Pour un contrôle plus fin (par exemple pour définir les valeurs maximum et minimum, vous devez créer une instance du formatteur, définir les propriétés comme vous le souhaitez et l'attacher au champ de texte en utilisant son setFormatter: méthode.

vous pouvez télécharger la classe de GitHub (y compris un exemple de projet)

13
répondu Abizern 2010-12-23 19:48:10

la bonne façon de procéder à partir de iOS 9 est:

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

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

alternativement:

NSLog(@"%@", [NSString localizedStringFromNumber:@(1)
                                     numberStyle:NSNumberFormatterOrdinalStyle]); // 1st
31
répondu Chris Nolet 2018-05-11 20:55:28

Cela fait l'affaire dans une méthode (pour l'anglais). Merci nickf https://stackoverflow.com/a/69284/1208690 pour le code original en PHP, je viens de l'adapter à 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;
}
22
répondu CmKndy 2017-05-23 10:31:19

D'autres solutions Swift ne produisent pas de résultat correct et contiennent des erreurs. J'ai traduit CmKndy solution en 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)"
    }

}

résultat de l'essai: 0e 1er 2ème 3e 4e 5ème Six Sept 8ème 9ème 10ème 11ème Douze Treize 14ème 15ème 16e Dix sept 18ème 19ème 20ème 21ème Vingt deux 23ème

14
répondu Greg Lukosek 2016-11-12 01:49:57

Comme d'iOS 9

Swift 3

let value = 1

let formatter = NumberFormatter()
formatter.numberStyle = .ordinal
formatter.string(from: NSNumber(short: value))
12
répondu Magoo 2018-05-21 09:19:17

ajout D'une autre implémentation comme méthode de classe. Je n'ai vu cette question postée qu'après l'avoir implémentée à partir d'un exemple en 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;
}
5
répondu jpittman 2012-06-07 00:39:19

c'est assez simple en anglais. Voici une extension swift:

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

alors appelez quelque chose comme:

    cell.label_position.text = (path.row + 1).ordinal
5
répondu superarts.org 2015-08-28 04:09:47

Voici une extension Swift compacte adaptée à tous les types d'entiers:

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

exemple d'usage:

let numbers = (0...30).map { "151910920".ordinalString() }
print(numbers.joinWithSeparator(", "))

sortie:

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

5
répondu maxkonovalov 2016-03-15 19:46:16

Je ne suis pas au courant de cette capacité. Toutefois, il est possible de le faire vous-même. En anglais, l'ordinal (th, st, nd, rd, etc) a un motif très simple:

si le nombre se termine par: = > Use:

  • 0 = > th
  • 1 = > st
  • 2 = > nd
  • 3 = > rd
  • 4 = > th
  • 5 = > th
  • 6 = > th
  • 7 = > th
  • 8 = > th
  • 9 = > th
  • 11 = > th
  • 12 = > th
  • 13 = > th

cela n'épelle pas le mot pour vous, mais cela vous permettra de faire quelque chose comme:" 42nd"," 1,340,697 th", etc.

cela devient plus compliqué si vous en avez besoin localisé.

3
répondu Dave DeLong 2010-07-22 20:44:53

Un nettoyage Swift version (en anglais seulement):

func ordinal(number: Int) -> String {
    if (11...13).contains(number % 100) {
        return "\(number)th"
    }
    switch number % 10 {
        case 1: return "\(number)st"
        case 2: return "\(number)nd"
        case 3: return "\(number)rd"
        default: return "\(number)th"
    }
}

peut être utilisé comme extension pour Int :

extension Int {

    func ordinal() -> String {
        return "\(self)\(ordinalSuffix())"
    }

    func ordinalSuffix() -> String {
        if (11...13).contains(self % 100) {
            return "th"
        }
        switch self % 10 {
            case 1: return "st"
            case 2: return "nd"
            case 3: return "rd"
            default: return "th"
        }
    }

}
3
répondu Eneko Alonso 2016-02-21 20:41:51

-- Swift 4 --

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

     print(day!)
     result - 1st
3
répondu Krunal Patel 2017-12-29 10:11:57

l'exemple suivant montre comment traiter un nombre. Il est en c # mais il peut facilement être converti à n'importe quelle langue.

http://www.bytechaser.com/en/functions/b6yhfyxh78/convert-number-to-ordinal-like-1st-2nd-in-c-sharp.aspx

2
répondu Alex 2010-07-22 20:41:43

cela convertira la date en chaîne et ajoutera aussi ordinal dans la date. Vous pouvez modifier la date formatte en changeant NSDateFormatter object

-(NSString*) getOrdinalDateString:(NSDate*)date
{
    NSString* string=@"";
    NSDateComponents *components = [[NSCalendar currentCalendar] components: NSCalendarUnitDay fromDate:date];

    if(components.day == 1 || components.day == 21 || components.day == 31)
        string = @"st";

    else if (components.day == 2 || components.day == 22)
        string = @"nd";

    else if (components.day == 3 || components.day == 23)
        string = @"rd";

    else
        string = @"th";


    NSDateFormatter *dateFormatte = [[NSDateFormatter alloc] init];
    [dateFormatte setFormatterBehavior:NSDateFormatterBehavior10_4];
    [dateFormatte setDateFormat:[NSString stringWithFormat:@"d'%@' MMMM yyyy",string]];

    NSString *dateString = [dateFormatte stringFromDate:date];
    return dateString;
}
1
répondu Milap Kundalia 2015-12-28 12:13:35

il y a une solution simple pour ce

let formatter = NumberFormatter()
formatter.numberStyle = .ordinal
let first = formatter.string(from: 1) // 1st
let second = formatter.string(from: 2) // 2nd

Referance: hackingwithswift.com

1
répondu ymutlu 2018-03-20 10:23:39

Voici une solution rapide qui tourne à travers les langues préférées de l'utilisateur jusqu'à ce qu'il en trouve une avec des règles connues (qui sont assez faciles à ajouter) pour les nombres ordinaux:

extension Int {
    var localizedOrdinal: String {

        func ordinalSuffix(int: Int) -> String {
            for language in NSLocale.preferredLanguages() as [String] {
                switch language {
                case let l where l.hasPrefix("it"):
                    return "°"
                case let l where l.hasPrefix("en"):
                    switch int {
                    case let x where x != 11 && x % 10 == 1:
                        return "st"
                    case let x where x != 12 && x % 10 == 2:
                        return "nd"
                    case let x where x != 13 && x % 10 == 3:
                        return "rd"
                    default:
                        return "st"
                    }
                default:
                    break
                }
            }
            return ""
        }

        return "\(self)" + ordinalSuffix(self)
    }
}
0
répondu Alnair 2014-11-18 14:17:11

beaucoup de solutions ici ne gèrent pas des nombres plus élevés comme 112. Voici une façon simple de le faire.

for(int i=0;i<1000;i++){
    int n = i;
    NSString* ordinal = @"th";
    if(n%10==1 && n%100!=11) ordinal = @"st";
    if(n%10==2 && n%100!=12) ordinal = @"nd";
    if(n%10==3 && n%100!=13) ordinal = @"rd";
    NSLog(@"You are the %d%@",i,ordinal);
}
0
répondu garafajon 2015-08-19 21:24:18

Voici une courte extension Int pour la langue anglaise qui rend compte aussi et affiche des nombres entiers négatifs correctement:

extension Int {
    func ordinal() -> String {
        let suffix: String!
        // treat negative numbers as positive for suffix
        let number = (self < 0 ? self * -1 : self)

        switch number % 10 {
        case 0:
            suffix = self != 0 ? "th" : ""
        case 1:
            suffix = "st"
        case 2:
            suffix = "nd"
        case 3:
            suffix = "rd"
        default:
            suffix = "th"
        }

        return String(self) + suffix
    }
}
0
répondu Luke Chase 2016-09-13 19:12:39
- (NSString *) formatOrdinalNumber:(NSInteger )number{
    NSString *result = nil;
    //0 remains just 0
    if (number == 0) {
        result = @"0";
    }

    //test for number between 3 and 21 as they follow a
    //slightly different rule and all end with th
    else if (number > 3 && number < 21)
    {
        result = [NSString stringWithFormat:@"%ld th",(long)number];
    }
    else {
        //return the last digit of the number e.g. 102 is 2
        NSInteger lastdigit = number % 10;
        switch (lastdigit)
        {
            case 1: result = [NSString stringWithFormat:@"%ld st",(long)number]; break;
            case 2: result = [NSString stringWithFormat:@"%ld nd",(long)number]; break;
            case 3: result = [NSString stringWithFormat:@"%ld rd",(long)number]; break;
            default: result = [NSString stringWithFormat:@"%ld th",(long)number];
        }
    }
    return result;
}
0
répondu Bhavesh Dhaduk 2017-05-05 07:04:21

C'était mon implémentation brute de force à prendre une représentation NSString* de la date et retourner la valeur ordinale. Je sens que c'est beaucoup plus facile à lire.

NSDictionary *ordinalDates = @{
    @"1": @"1st",
    @"2": @"2nd",
    @"3": @"3rd",
    @"4": @"4th",
    @"5": @"5th",
    @"6": @"6th",
    @"7": @"7th",
    @"8": @"8th",
    @"9": @"9th",
    @"10": @"10th",
    @"11": @"11th",
    @"12": @"12th",
    @"13": @"13th",
    @"14": @"14th",
    @"15": @"15th",
    @"16": @"16th",
    @"17": @"17th",
    @"18": @"18th",
    @"19": @"19th",
    @"20": @"20th",
    @"21": @"21st",
    @"22": @"22nd",
    @"23": @"23rd",
    @"24": @"24th",
    @"25": @"25th",
    @"26": @"26th",
    @"27": @"27th",
    @"28": @"28th",
    @"29": @"29th",
    @"30": @"30th",
    @"31": @"31st" };
-4
répondu ahall 2014-02-03 15:51:29