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.

Enyra
quelle

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.

Dave DeLong
quelle
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).

Barry Wark
quelle
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
Kevin R.
quelle
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].

ma11hew28
quelle
50

Sie können dies auch tun:

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

Habe Spaß!

MacMark
quelle
26

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

NSString* val = @"12";
[NSNumber numberWithInt:[val intValue]];
Ad1905
quelle
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
miker
quelle
das funktioniert bei mir nicht Ich entwickle für 5.0 mit xcode 4.3.2. irgendwelche Ideen warum?
Acecapades
6

Ich wollte einen String in einen Double konvertieren. Diese obige Antwort hat bei mir nicht ganz funktioniert. Aber das tat: Wie mache ich String-Konvertierungen in Objective-C?

Alles was ich getan habe war:

double myDouble = [myString doubleValue];
Anthony
quelle
Dadurch wird die NSInteger nicht in eine NSNumber konvertiert. Es wandelt es in ein Doppel um.
FabKremer
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];
DNA App Lab
quelle
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.

JeanNicolas
quelle
2

Was ist mit Cs Standard atoi?

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

Denken Sie, dass es irgendwelche Einschränkungen gibt?

Martin
quelle
2

Sie können einfach [string intValue]oder [string floatValue]oder [string doubleValue]etc. Verwenden

Sie können auch NSNumberFormatterKlasse verwenden:

user1479883
quelle
2

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

[NSNumber numberWithInt:[@"put your string here" intValue]]
Parv Bhasker
quelle
1
NSDecimalNumber *myNumber = [NSDecimalNumber decimalNumberWithString:@"123.45"];
NSLog(@"My Number : %@",myNumber);
Sandip Patel - SM
quelle
0

Arbeitete in Swift 3

NSDecimalNumber(string: "Your string") 
user431791
quelle
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

Ashu
quelle
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.

Rizwan Ahmed
quelle
-1
extension String {

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

let someFloat = "12.34".numberValue
Ankit garg
quelle