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.

Enyra
sumber

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.

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

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

ma11hew28
sumber
50

Anda juga dapat melakukan ini:

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

Selamat bersenang-senang!

MacMark
sumber
26

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

NSString* val = @"12";
[NSNumber numberWithInt:[val intValue]];
Ad1905
sumber
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
miker
sumber
ini tidak bekerja untuk saya. Saya sedang mengembangkan untuk 5.0 dengan xcode 4.3.2. ada ide kenapa?
acecapades
6

Saya ingin mengubah string menjadi dobel. Jawaban di atas tidak berhasil bagi saya. Tapi ini berhasil: Bagaimana melakukan konversi string di Objective-C?

Yang saya cukup banyak lakukan adalah:

double myDouble = [myString doubleValue];
Anthony
sumber
Ini tidak mengubah NSInteger ke NSNumber. Itu mengubahnya menjadi ganda.
FabKremer
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];
Lab Aplikasi DNA
sumber
4

Saya pikir NSDecimalNumber akan melakukannya:

Contoh:

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

NSDecimalNumber adalah subkelas dari NSNumber, jadi pengecoran implisit diperbolehkan.

JeanNicolas
sumber
2

Bagaimana dengan standar C atoi?

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

Apakah Anda pikir ada peringatan?

martin
sumber
2

Anda bisa menggunakan [string intValue]atau [string floatValue]atau [string doubleValue]lainnya

Anda juga dapat menggunakan NSNumberFormatterkelas:

pengguna1479883
sumber
2

Anda juga dapat melakukan hal ini seperti dukungan kode 8.3.3 ios 10.3

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

Bekerja di Swift 3

NSDecimalNumber(string: "Your string") 
pengguna431791
sumber
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

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

Rizwan Ahmed
sumber
-1
extension String {

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

let someFloat = "12.34".numberValue
Ankit garg
sumber