Comment convertir une NSString en un NSNumber


569

Comment puis - je convertir un NSStringcontenant un certain nombre de tout type de données primitive (par exemple int, float, char, unsigned int, etc.)? Le problème est que je ne sais pas quel type de numéro la chaîne contiendra lors de l'exécution.

J'ai une idée de comment le faire, mais je ne sais pas si cela fonctionne avec n'importe quel type, également des valeurs non signées et à virgule flottante:

long long scannedNumber;
NSScanner *scanner = [NSScanner scannerWithString:aString];
[scanner scanLongLong:&scannedNumber]; 
NSNumber *number = [NSNumber numberWithLongLong: scannedNumber];

Merci pour l'aide.

Réponses:


1245

Utilisez un NSNumberFormatter:

NSNumberFormatter *f = [[NSNumberFormatter alloc] init];
f.numberStyle = NSNumberFormatterDecimalStyle;
NSNumber *myNumber = [f numberFromString:@"42"];

Si la chaîne n'est pas un nombre valide, elle le myNumbersera nil. S'il s'agit d'un nombre valide, vous avez maintenant toute la NSNumberbonté de déterminer de quel type de numéro il s'agit.


16
Pour les personnes où cela ne semble pas fonctionner: vérifiez si cela est lié à votre environnement local. Le NSNumberFormatter (pour autant que je sache) utilise par défaut les paramètres régionaux américains, c'est-à-dire s'attend à ce que le séparateur décimal soit le "." personnage. Si vous utilisez "," pour séparer la fraction, vous devrez peut-être dire au formateur d'utiliser vos paramètres régionaux actuels: [f setLocale: [NSLocale currentLocale]];
pille

2
@pille par défaut, la locale est la +currentLocale, mais vous avez raison; il faut toujours tenir compte des paramètres régionaux lors de la conversion de trucs vers et depuis une forme lisible par l'homme.
Dave DeLong

Où avez-vous constaté qu'il s'agissait de currentLocale par défaut? Je peux confirmer que numberFromString utilise la notation par points même sur un téléphone français où la virgule est utilisée. Je peux confirmer que par défaut, lorsque vous sortez un nombre, il utilise les paramètres régionaux actuels par défaut
allaire

Mais que faire si la chaîne peut contenir int ou float?
GeneCode

179

Vous pouvez utiliser -[NSString integerValue], -[NSString floatValue]etc. Cependant, la manière correcte (paramètres régionaux, etc.) pour ce faire est d'utiliser ce -[NSNumberFormatter numberFromString:]qui vous donnera un NSNumber converti à partir des environnements locaux appropriés et compte tenu des paramètres du NSNumberFormatter(y compris si elle permettra flottante valeurs en points).


27
+ q En fonction de la situation, la non-sensibilité locale peut être en fait la bonne façon.
Thilo

2
J'ai dû me convertir @"2000"en un intet j'ai [@"2000" integerValue]bien travaillé et c'est un peu plus simple pour mon cas.
Besi

2
Il existe également d'énormes différences de performances entre ces méthodes.
Tom Andersen

2
cela ne fonctionne pas avec ARC: il ne convertira pas NSInteger en NSNumber. Je dois continuer à utiliser[NSNumber numberWithInteger ...]
apprenant

Ce que @Thilo a dit. "Correct" et "locale-sensitive" ne sont pas synonymes. La bonne chose à faire dépend en fait de la façon dont le nombre est entré dans la chaîne en premier lieu. Si vous le lisez à partir de l'entrée utilisateur, alors vous êtes sensible au local. À partir de toute autre source (c'est-à-dire que vous l'avez mise par programme, vous la consommez dans le cadre de la réponse d'une API externe, etc.), la sensibilité locale n'est pas appropriée et pourrait même donner des résultats incorrects.
aroth

138

Objectif c

(Remarque: cette méthode ne fonctionne pas bien avec les différences de paramètres régionaux, mais est légèrement plus rapide que a NSNumberFormatter)

NSNumber *num1 = @([@"42" intValue]);
NSNumber *num2 = @([@"42.42" floatValue]);

Rapide

Manière simple mais sale

// Swift 1.2
if let intValue = "42".toInt() {
    let number1 = NSNumber(integer:intValue)
}

// Swift 2.0
let number2 = Int("42')

// Swift 3.0
NSDecimalNumber(string: "42.42") 

// Using NSNumber
let number3 = NSNumber(float:("42.42" as NSString).floatValue)

L'extension-way C'est mieux, vraiment, car il jouera bien avec les locales et les décimales.

extension String {

    var numberValue:NSNumber? {
        let formatter = NSNumberFormatter()
        formatter.numberStyle = .DecimalStyle
        return formatter.number(from: self)
    }
}

Maintenant, vous pouvez simplement faire:

let someFloat = "42.42".numberValue
let someInt = "42".numberValue

1
Je préfère cela en fonction du profilage lorsque j'analysais une grande quantité de valeurs de chaîne. L'utilisation de cette syntaxe plutôt qu'un NSNumberFormatter a conduit à une réduction significative du temps passé à analyser la chaîne en NSNumber. Et oui, NSNumberFormatter a été mis en cache et réutilisé.
androider

3
cette syntaxe littérale n'existait pas lorsque cette question a été posée. Je dirais que c'est la bonne réponse de nos jours cependant.
Chris

1
Je suis d'accord, mais notez que certains autres pays utilisent le ,et .l'inverse (par exemple 42.000,42. Quelque chose floatValuene tient probablement pas compte?
Kevin R

1
C'est la meilleure solution ici, mais je viens de faire un test et vous perdrez une précision non signée alors ATTENTION !!!
Stoff81

Dans mon cas d'utilisation, j'avais besoin d'obtenir une clé de dictionnaire NSNumber à partir d'une NSString, donc cela @([@"42" intValue])fonctionnait parfaitement. Pas inquiet pour Locale.
Chuck Krutsinger

86

Pour les chaînes commençant par des nombres entiers, par exemple @"123", @"456 ft", @"7.89", etc., l' utilisation -[NSString integerValue].

C'est @([@"12.8 lbs" integerValue])comme faire [NSNumber numberWithInteger:12].


50

Vous pouvez également le faire:

NSNumber *number = @([dictionary[@"id"] intValue]]);

S'amuser!


26

Si vous savez que vous recevez des nombres entiers, vous pouvez utiliser:

NSString* val = @"12";
[NSNumber numberWithInt:[val intValue]];

11

Voici un exemple de travail de NSNumberFormatter lisant le numéro localisé NSString (xCode 3.2.4, osX 10.6), pour économiser aux autres les heures que je viens de passer à jouer. Attention: bien qu'il puisse gérer les blancs de fin ("8 765,4" fonctionne), cela ne peut pas gérer les espaces blancs en tête et cela ne peut pas gérer les caractères de texte errant. (Chaînes d'entrée incorrectes: "8" et "8q" et "8 q".)

NSString *tempStr = @"8,765.4";  
     // localization allows other thousands separators, also.
NSNumberFormatter * myNumFormatter = [[NSNumberFormatter alloc] init];
[myNumFormatter setLocale:[NSLocale currentLocale]]; // happen by default?
[myNumFormatter setFormatterBehavior:NSNumberFormatterBehavior10_4];
     // next line is very important!
[myNumFormatter setNumberStyle:NSNumberFormatterDecimalStyle]; // crucial

NSNumber *tempNum = [myNumFormatter numberFromString:tempStr];
NSLog(@"string '%@' gives NSNumber '%@' with intValue '%i'", 
    tempStr, tempNum, [tempNum intValue]);
[myNumFormatter release];  // good citizen

ça ne marche pas pour moi. Je développe pour 5.0 avec xcode 4.3.2. des idées pourquoi?
acecapades


5

Merci a tous! Je suis une rétroaction combinée et parviens enfin à convertir de la saisie de texte (chaîne) en entier. De plus, il pourrait me dire si l'entrée est un entier :)

NSNumberFormatter * f = [[NSNumberFormatter alloc] init];
[f setNumberStyle:NSNumberFormatterDecimalStyle];
NSNumber * myNumber = [f numberFromString:thresholdInput.text];

int minThreshold = [myNumber intValue]; 

NSLog(@"Setting for minThreshold %i", minThreshold);

if ((int)minThreshold < 1 )
{
    NSLog(@"Not a number");
}
else
{
    NSLog(@"Setting for integer minThreshold %i", minThreshold);
}
[f release];

4

Je pense que NSDecimalNumber le fera:

Exemple:

NSNumber *theNumber = [NSDecimalNumber decimalNumberWithString:[stringVariable text]]];

NSDecimalNumber est une sous-classe de NSNumber, la conversion implicite est donc autorisée.


2

Qu'en est-il de la norme C atoi?

int num = atoi([scannedNumber cStringUsingEncoding:NSUTF8StringEncoding]);

Pensez-vous qu'il y ait des mises en garde?


2

Vous pouvez simplement utiliser [string intValue]ou [string floatValue]ou [string doubleValue]etc.

Vous pouvez également utiliser la NSNumberFormatterclasse:


2

vous pouvez également faire comme ce code support 8.3.3 ios 10.3

[NSNumber numberWithInt:[@"put your string here" intValue]]

1
NSDecimalNumber *myNumber = [NSDecimalNumber decimalNumberWithString:@"123.45"];
NSLog(@"My Number : %@",myNumber);

0

A travaillé dans Swift 3

NSDecimalNumber(string: "Your string") 

0

Je sais que c'est très tard mais le code ci-dessous fonctionne pour moi.

Essayez ce code

NSNumber *number = @([dictionary[@"keyValue"] intValue]]);

Cela peut vous aider. Merci


0

Essaye ça

NSNumber *yourNumber = [NSNumber numberWithLongLong:[yourString longLongValue]];

Remarque - J'ai utilisé longLongValue selon mes besoins. Vous pouvez également utiliser integerValue, longValue ou tout autre format en fonction de vos besoins.


-1
extension String {

    var numberValue:NSNumber? {
        let formatter = NumberFormatter()
        formatter.numberStyle = .decimal
        return formatter.number(from: self)
    }
}

let someFloat = "12.34".numberValue
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.