Bagaimana cara mengubah NSString menjadi NSNumber


569

Bagaimana saya bisa mengkonversi NSStringberisi sejumlah tipe data primitif (misalnya int, float, char, unsigned int, dll)? Masalahnya adalah, saya tidak tahu tipe nomor mana yang akan berisi string saat runtime.

Saya punya ide bagaimana melakukannya, tetapi saya tidak yakin apakah ini bekerja dengan semua tipe, juga nilai unsigned dan floating point:

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

Terima kasih untuk bantuannya.

Jawaban:


1245

Gunakan NSNumberFormatter:

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

Jika string bukan angka yang valid, maka myNumberakan menjadi nil. Jika itu nomor yang valid, maka sekarang Anda memiliki semua NSNumberkebaikan untuk mengetahui nomor apa itu sebenarnya.


16
Untuk orang yang sepertinya tidak berfungsi: Periksa apakah ini terkait dengan lokal Anda. NSNumberFormatter (sejauh yang saya tahu) secara default menggunakan lokal AS, yaitu mengharapkan pemisah desimal menjadi "." karakter. Jika Anda menggunakan "," untuk memisahkan fraksi, Anda mungkin perlu memberi tahu formatter untuk menggunakan lokal Anda saat ini: [f setLocale: [NSLocale currentLocale]];
pille

2
@pille secara default locale adalah +currentLocale, tetapi Anda benar; kita harus selalu mempertimbangkan lokal ketika berhadapan dengan mengkonversi barang ke-dan-dari bentuk yang bisa dibaca manusia.
Dave DeLong

Di mana Anda menemukan bahwa itu adalah CurrentLocale secara default? Saya dapat mengonfirmasi bahwa numberFromString menggunakan notasi titik bahkan pada telepon Prancis di mana koma digunakan. Saya dapat mengonfirmasi bahwa secara default, ketika Anda mengeluarkan angka, ia menggunakan lokal saat ini secara default
allaire

Tetapi bagaimana jika string dapat berisi int atau float?
GeneCode

179

Anda dapat menggunakan -[NSString integerValue],, -[NSString floatValue]dll. Namun, cara yang benar (sensitif-lokal, dll.) Untuk melakukan ini adalah dengan menggunakan -[NSNumberFormatter numberFromString:]yang akan memberi Anda NSNumber yang dikonversi dari lokal yang sesuai dan diberikan pengaturan NSNumberFormatter(termasuk apakah itu akan memungkinkan mengambang nilai titik).


27
+ q Bergantung pada situasinya, non-lokal-sensitif mungkin sebenarnya adalah cara yang benar.
Thilo

2
Saya harus mengonversi @"2000"ke intdan [@"2000" integerValue]bekerja dengan baik dan sedikit lebih sederhana untuk kasus saya.
Besi

2
Ada juga perbedaan kinerja yang sangat besar di antara metode-metode ini.
Tom Andersen

2
ini tidak bekerja dengan ARC: ini tidak akan mengubah NSInteger ke NSNumber. Saya harus menggunakan lebih lanjut[NSNumber numberWithInteger ...]
pelajar

Apa yang dikatakan @Thilo. "Benar" dan "sensitif-lokal" bukan sinonim. Hal yang benar untuk dilakukan sebenarnya tergantung pada bagaimana nomor masuk ke string di tempat pertama. Jika Anda membacanya dari input pengguna, maka yang peka-lokal adalah yang Anda inginkan. Dari sumber lain (mis. Anda meletakkannya di sana secara terprogram, Anda mengonsumsinya sebagai bagian dari respons dari beberapa API eksternal, dll.) Peka lokal tidak tepat dan bahkan dapat memberikan hasil yang salah.
Agustus

138

Objektif-C

(Catatan: metode ini tidak cocok dengan perbedaan lokal, tetapi sedikit lebih cepat dari a NSNumberFormatter)

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

Cepat

Cara sederhana tapi kotor

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

Cara ekstensi Ini lebih baik, sungguh, karena itu akan bermain baik dengan lokal dan desimal.

extension String {

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

Sekarang Anda bisa melakukannya:

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

1
Saya lebih suka ini berdasarkan profil ketika saya mem-parsing sejumlah besar nilai string. Menggunakan sintaks ini daripada NSNumberFormatter menyebabkan pengurangan waktu yang dihabiskan untuk mengurai string ke NSNumber. Dan ya, NSNumberFormatter di-cache dan digunakan kembali.
androider

3
sintaks literal ini tidak ada ketika pertanyaan ini diajukan. Saya akan mengatakan ini adalah jawaban yang benar saat ini.
Chris

1
Saya setuju, tetapi perlu dicatat bahwa beberapa negara lain menggunakan ,dan .sebaliknya (mis 42.000,42. Sesuatu floatValuemungkin tidak masuk akal?
Kevin R

1
Ini adalah solusi terbaik di sini, namun saya baru saja menjalankan tes dan Anda akan kehilangan presisi tanpa tanda tangan jadi HATI-HATI !!!
Stoff81

Dalam kasus penggunaan saya, saya perlu mendapatkan kunci kamus NSNumber dari NSString, jadi @([@"42" intValue])berfungsi dengan baik. Tidak khawatir tentang Lokal.
Chuck Krutsinger

86

Untuk string dimulai dengan bilangan bulat, misalnya, @"123", @"456 ft", @"7.89", dll, penggunaan -[NSString integerValue].

Jadi, @([@"12.8 lbs" integerValue])seperti melakukan [NSNumber numberWithInteger:12].


50

Anda juga dapat melakukan ini:

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

Selamat bersenang-senang!


26

Jika Anda tahu bahwa Anda menerima bilangan bulat, Anda dapat menggunakan:

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

11

Berikut adalah contoh NSNumberFormatter yang dapat membaca nomor lokal NSString (xCode 3.2.4, osX 10.6), untuk menghemat waktu yang saya habiskan untuk bermain-main dengan orang lain. Hati-hati: meskipun dapat menangani trailing blank ("8,765,4" berfungsi), ini tidak dapat menangani spasi putih terdepan dan ini tidak dapat menangani karakter teks liar. (String input buruk: "8" dan "8q" dan "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

ini tidak bekerja untuk saya. Saya sedang mengembangkan untuk 5.0 dengan xcode 4.3.2. ada ide kenapa?
acecapades


5

Terima kasih semuanya! Saya umpan balik gabungan dan akhirnya berhasil mengkonversi dari input teks (string) ke Integer. Plus itu bisa memberi tahu saya apakah input bilangan bulat :)

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

Saya pikir NSDecimalNumber akan melakukannya:

Contoh:

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

NSDecimalNumber adalah subkelas dari NSNumber, jadi pengecoran implisit diperbolehkan.


2

Bagaimana dengan standar C atoi?

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

Apakah Anda pikir ada peringatan?



2

Anda juga dapat melakukan hal ini seperti dukungan kode 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

Saya tahu ini sangat terlambat tetapi kode di bawah ini berfungsi untuk saya.

Coba kode ini

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

Ini dapat membantu Anda. Terima kasih


0

Coba ini

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

Catatan - Saya telah menggunakan longLongValue sesuai kebutuhan saya. Anda juga dapat menggunakan integerValue, longValue, atau format lainnya tergantung pada kebutuhan Anda.


-1
extension String {

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

let someFloat = "12.34".numberValue
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.