So konvertieren Sie einen NSString in eine NSNumber


569

Wie kann ich konvertiere ein NSStringeine Reihe von jedem primitiven Datentyp enthält (zB int, float, char, unsigned int, etc.)? Das Problem ist, ich weiß nicht, welchen Nummerntyp die Zeichenfolge zur Laufzeit enthalten wird.

Ich habe eine Idee, wie es geht, bin mir aber nicht sicher, ob dies mit einem Typ funktioniert, auch mit vorzeichenlosen und Gleitkommawerten:

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

Danke für die Hilfe.

Antworten:


1245

Verwenden Sie ein NSNumberFormatter:

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

Wenn die Zeichenfolge keine gültige Zahl ist, ist dies myNumberder Fall nil. Wenn es sich um eine gültige Nummer handelt, können Sie jetzt NSNumberherausfinden, um welche Art von Nummer es sich tatsächlich handelt.


16
Für Personen, bei denen es nicht zu funktionieren scheint: Überprüfen Sie, ob es mit Ihrem Gebietsschema zusammenhängt. Der NSNumberFormatter (soweit ich weiß) verwendet standardmäßig das US-Gebietsschema, dh, das Dezimaltrennzeichen ist das "." Charakter. Wenn Sie den Bruch mit "," trennen, müssen Sie dem Formatierer möglicherweise mitteilen, dass er Ihr aktuelles Gebietsschema verwenden soll: [f setLocale: [NSLocale currentLocale]];
Pille

2
@pille Standardmäßig ist das Gebietsschema das +currentLocale, aber Sie haben Recht . Man muss immer das Gebietsschema berücksichtigen, wenn man Dinge in eine von Menschen lesbare Form konvertiert.
Dave DeLong

Wo haben Sie festgestellt, dass es sich standardmäßig um currentLocale handelt? Ich kann bestätigen, dass numberFromString die Punktnotation auch auf einem französischen Telefon verwendet, auf dem Komma verwendet wird. Ich kann bestätigen, dass bei der Ausgabe einer Nummer standardmäßig das aktuelle Gebietsschema verwendet wird
allaire

Was aber, wenn der String entweder int oder float enthalten kann?
GeneCode

179

Sie können verwendet werden -[NSString integerValue], -[NSString floatValue]usw. Allerdings ist die korrekte (locale-sensitive, etc.) Art und Weise , dies zu tun zu verwenden ist , -[NSNumberFormatter numberFromString:]die Sie ein NSNumber aus dem entsprechenden Gebietsschema umgewandelt und gegeben , die Einstellungen des NSNumberFormatter(einschließlich , ob es schwimmend erlaubt Punktwerte).


27
+ q Abhängig von der Situation kann es sein, dass nicht für das Gebietsschema empfindlich ist.
Thilo

2
Ich hatte zu konvertieren , @"2000"um ein intund [@"2000" integerValue]arbeitete gut und ist ein wenig einfacher für meinen Fall.
Besi

2
Es gibt auch große Leistungsunterschiede zwischen diesen Methoden.
Tom Andersen

2
Dies funktioniert nicht mit ARC: NSInteger wird nicht in NSNumber konvertiert. Ich muss weiter verwenden[NSNumber numberWithInteger ...]
Lernende

Was @Thilo gesagt hat. "Richtig" und "Gebietsschemasensitiv" sind keine Synonyme. Die richtige Vorgehensweise hängt davon ab, wie die Nummer überhaupt in die Zeichenfolge gelangt ist. Wenn Sie es aus Benutzereingaben lesen, möchten Sie lokal sensibel sein. Aus einer anderen Quelle (dh Sie legen es programmgesteuert dort ab, verbrauchen Sie es als Teil der Antwort von einer externen API usw.) ist local-sensitive nicht geeignet und kann sogar zu falschen Ergebnissen führen.
aroth

138

Ziel c

(Hinweis: Diese Methode spielt nicht gut mit unterschiedlichen Gebietsschemas, ist jedoch etwas schneller als a NSNumberFormatter)

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

Schnell

Einfach aber schmutzig

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

Der Erweiterungsweg Das ist wirklich besser, weil es gut mit Gebietsschemas und Dezimalstellen funktioniert.

extension String {

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

Jetzt können Sie einfach tun:

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

1
Ich bevorzuge dies basierend auf der Profilerstellung, wenn ich eine große Anzahl von Zeichenfolgenwerten analysiert habe. Die Verwendung dieser Syntax anstelle eines NSNumberFormatter führte zu einer erheblichen Reduzierung des Zeitaufwands für das Parsen des Strings in NSNumber. Und ja, der NSNumberFormatter wurde zwischengespeichert und wiederverwendet.
Androider

3
Diese wörtliche Syntax existierte nicht, als diese Frage gestellt wurde. Ich würde sagen, dass dies heutzutage die richtige Antwort ist.
Chris

1
Ich stimme zu, aber beachten Sie, dass einige andere Länder das ,und .umgekehrt verwenden (z 42.000,42. B. etwas, das floatValuewahrscheinlich nicht berücksichtigt wird?
Kevin R

1
Dies ist die schönste Lösung hier, aber ich habe gerade einen Test durchgeführt und Sie werden die vorzeichenlose Präzision verlieren, also achten Sie darauf !!!
Stoff81

In meinem Anwendungsfall musste ich einen NSNumber-Wörterbuchschlüssel von einem NSString erhalten, damit @([@"42" intValue])er perfekt funktionierte. Keine Sorge um das Gebietsschema.
Chuck Krutsinger

86

Bei Strings mit Zahlen beginnen, zum Beispiel @"123", @"456 ft", @"7.89"usw. Verwendung -[NSString integerValue].

Also, @([@"12.8 lbs" integerValue])ist wie zu tun [NSNumber numberWithInteger:12].


50

Sie können dies auch tun:

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

Habe Spaß!


26

Wenn Sie wissen, dass Sie Ganzzahlen erhalten, können Sie Folgendes verwenden:

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

11

Hier ist ein Arbeitsbeispiel von NSNumberFormatter, das die lokalisierte Nummer NSString (xCode 3.2.4, osX 10.6) liest, um anderen die Stunden zu ersparen, die ich gerade damit verbracht habe, herumzuspielen. Achtung: Während es nachfolgende Leerzeichen verarbeiten kann ("8.765,4" funktioniert), kann dies keine führenden Leerzeichen und keine streunenden Textzeichen verarbeiten. (Fehlerhafte Eingabezeichenfolgen: "8" und "8q" und "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

das funktioniert bei mir nicht Ich entwickle für 5.0 mit xcode 4.3.2. irgendwelche Ideen warum?
Acecapades


5

Vielen Dank an alle! Ich bin kombiniertes Feedback und schaffe es endlich, von einer Texteingabe (Zeichenfolge) in eine Ganzzahl umzuwandeln. Außerdem könnte es mir sagen, ob die Eingabe eine Ganzzahl ist :)

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

Ich denke, NSDecimalNumber wird es tun:

Beispiel:

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

NSDecimalNumber ist eine Unterklasse von NSNumber, daher ist implizites Casting zulässig.


2

Was ist mit Cs Standard atoi?

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

Denken Sie, dass es irgendwelche Einschränkungen gibt?



2

Sie können auch diesen Code 8.3.3 ios 10.3 unterstützen

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

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


0

Ich weiß, dass dies sehr spät ist, aber der folgende Code funktioniert für mich.

Versuchen Sie diesen Code

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

Dies kann Ihnen helfen. Vielen Dank


0

Versuche dies

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

Hinweis - Ich habe longLongValue gemäß meiner Anforderung verwendet. Sie können je nach Ihren Anforderungen auch integerValue, longValue oder ein anderes Format verwenden.


-1
extension String {

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

let someFloat = "12.34".numberValue
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.