Come convertire un NSString in un NSNumber


569

Come posso convertire una NSStringcontenente un numero di qualsiasi tipo di dati di base (ad esempio int, float, char, unsigned int, etc.)? Il problema è che non so quale tipo di numero conterrà la stringa in fase di esecuzione.

Ho un'idea di come farlo, ma non sono sicuro che funzioni con qualsiasi tipo, anche con valori non firmati e in virgola mobile:

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

Grazie per l'aiuto.

Risposte:


1245

Usa un NSNumberFormatter:

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

Se la stringa non è un numero valido, myNumberlo sarà nil. Se è un numero valido, ora hai tutta la NSNumberbontà di capire che tipo di numero è in realtà.


16
Per le persone in cui non sembra funzionare: controlla se è correlato alla tua lingua. NSNumberFormatter (per quanto ne so) per impostazione predefinita utilizza le impostazioni internazionali degli Stati Uniti, ovvero prevede che il separatore decimale sia il "." carattere. Se si utilizza "," per separare la frazione, potrebbe essere necessario indicare al formattatore di utilizzare la locale corrente: [f setLocale: [NSLocale currentLocale]];
pille,

2
@pille per impostazione predefinita, la locale è la +currentLocale, ma hai ragione; bisogna sempre considerare le impostazioni locali quando si ha a che fare con la conversione di materiale in forma leggibile dall'uomo.
Dave DeLong,

Dove hai scoperto che era CurrentLocale per impostazione predefinita? Posso confermare che numberFromString utilizza la notazione punto anche su un telefono francese in cui viene utilizzata la virgola. Posso confermare che per impostazione predefinita, quando si emette un numero, utilizza l'impostazione internazionale corrente per impostazione predefinita
allaire

Ma cosa succede se la stringa può contenere int o float?
GeneCode

179

È possibile utilizzare -[NSString integerValue], -[NSString floatValue]ecc. Tuttavia, il modo corretto (sensibile -[NSNumberFormatter numberFromString:]alle impostazioni locali, ecc.) Di fare ciò è utilizzare che ti darà un NSNumber convertito dalle impostazioni locali appropriate e dato le impostazioni del NSNumberFormatter(incluso se consentirà valori punto).


27
+ q A seconda della situazione, la sensibilità non locale può effettivamente essere il modo corretto.
Thilo,

2
Ho dovuto convertire @"2000"in un inte ha [@"2000" integerValue]funzionato bene ed è un po 'più semplice per il mio caso.
Besi,

2
Ci sono anche enormi differenze di prestazioni tra questi metodi.
Tom Andersen,

2
questo non funziona con ARC: non converte NSInteger in NSNumber. Devo usare ulteriormente[NSNumber numberWithInteger ...]
studente

Cosa ha detto @Thilo. "Corretto" e "sensibile alle impostazioni locali" non sono sinonimi. La cosa corretta da fare in realtà dipende da come il numero è entrato nella stringa in primo luogo. Se lo leggi dall'input dell'utente, la sensibilità locale è ciò che desideri. Da qualsiasi altra fonte (cioè lo metti lì a livello di codice, lo stai consumando come parte della risposta da alcune API esterne, ecc.) Sensibile al locale non è appropriato e potrebbe persino dare risultati errati.
aroth

138

Objective-C

(Nota: questo metodo non funziona bene con le differenze locali, ma è leggermente più veloce di un NSNumberFormatter)

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

veloce

Modo semplice ma sporco

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

Il modo di estensione Questo è meglio, davvero, perché giocherà bene con locali e decimali.

extension String {

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

Ora puoi semplicemente fare:

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

1
Preferisco questo basato sulla profilazione quando stavo analizzando una grande quantità di valori di stringa. L'uso di questa sintassi anziché di un NSNumberFormatter ha comportato una significativa riduzione del tempo impiegato per l'analisi della stringa in NSNumber. E sì, NSNumberFormatter è stato memorizzato nella cache e riutilizzato.
androider

3
questa sintassi letterale non esisteva quando fu posta questa domanda. Oggi direi che questa è la risposta corretta.
Chris,

1
Sono d'accordo, ma nota che alcuni altri paesi usano il contrario ,e .viceversa (es 42.000,42. Qualcosa floatValueprobabilmente non tiene conto?
Kevin R

1
Questa è la soluzione più bella qui, tuttavia ho appena eseguito un test e perderai precisione senza segno, quindi GUARDA !!!
Stoff81,

Nel mio caso d'uso, avevo bisogno di ottenere una chiave del dizionario NSNumber da una NSString, quindi ha @([@"42" intValue])funzionato perfettamente. Non preoccupato per Locale.
Chuck Krutsinger,

86

Per le stringhe che iniziano con i numeri interi, ad esempio, @"123", @"456 ft", @"7.89", ecc, l'uso -[NSString integerValue].

Quindi, @([@"12.8 lbs" integerValue])è come fare [NSNumber numberWithInteger:12].


50

Puoi anche fare questo:

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

Divertiti!


26

Se sai di ricevere numeri interi, puoi utilizzare:

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

11

Ecco un esempio funzionante di NSNumberFormatter che legge il numero localizzato NSString (xCode 3.2.4, osX 10.6), per salvare gli altri nelle ore che ho appena passato in giro. Attenzione: mentre è in grado di gestire gli spazi vuoti finali ("8.765,4" funziona), questo non può gestire lo spazio bianco iniziale e non può gestire i caratteri di testo randagi. (Stringhe di input errate: "8" e "8q" e "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

questo non funziona per me. Sto sviluppando per 5.0 con xcode 4.3.2. qualche idea sul perché?
Acecapades,


5

Ringrazia tutti! Sono un feedback combinato e finalmente riesco a convertire da input di testo (stringa) a Integer. Inoltre potrebbe dirmi se l'input è intero :)

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

Penso che NSDecimalNumber lo farà:

Esempio:

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

NSDecimalNumber è una sottoclasse di NSNumber, pertanto è consentito il cast implicito.


2

E lo standard di C atoi?

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

Pensi che ci siano avvertenze?



2

puoi anche fare come questo codice 8.3.3 ios 10.3 support

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

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

0

Ha lavorato in Swift 3

NSDecimalNumber(string: "Your string") 

0

So che è molto tardi, ma sotto il codice funziona per me.

Prova questo codice

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

Questo può aiutarti. Grazie


0

Prova questo

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

Nota: ho usato longLongValue secondo il mio requisito. È inoltre possibile utilizzare integerValue, longValue o qualsiasi altro formato in base alle proprie esigenze.


-1
extension String {

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

let someFloat = "12.34".numberValue
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.