NSString'i NSNumber'a dönüştürme


569

Nasıl dönüştürebilir NSString(örneğin bir temel veri türü bir dizi ihtiva eden int, float, char, unsigned int, vs.)? Sorun, dize çalışma zamanında hangi sayı türü içereceğini bilmiyorum.

Nasıl yapılacağına dair bir fikrim var, ancak bunun herhangi bir tür, işaretsiz ve kayan nokta değerleri ile çalışıp çalışmadığından emin değilim:

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

Yardım için teşekkürler.

Yanıtlar:


1245

Şunu kullanın NSNumberFormatter:

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

Dize geçerli bir sayı değilse myNumber, olur nil. Geçerli bir sayı ise, NSNumbergerçekte ne tür bir sayı olduğunu anlamak için tüm iyiliğe sahipsiniz .


16
Çalışmıyor gibi görünen insanlar için: Yerel ayarınızla ilgili olup olmadığını kontrol edin. NSNumberFormatter (bildiğim kadarıyla) varsayılan olarak ABD yerel ayarını kullanır, yani ondalık ayırıcının "" olmasını bekler. karakter. Kesiri ayırmak için "," kullanırsanız, biçimlendiriciye geçerli yerel ayarınızı kullanmasını söylemeniz gerekebilir: [f setLocale: [NSLocale currentLocale]];
pille

2
@pille varsayılan olarak yerel ayardır +currentLocale, ancak haklısınız; insan tarafından okunabilir forma ve forma dönüştürülürken her zaman yerel ayar dikkate alınmalıdır.
Dave DeLong

Varsayılan olarak currentLocale olduğunu nereden buldunuz? NumberFromString'in virgül kullanılan bir Fransız telefonda bile nokta gösterimi kullandığını doğrulayabilirim. Varsayılan olarak, bir sayı
çıkardığınızda

Peki dize int veya float içerebilirse ne olur?
GeneCode

179

Sen kullanabilirsiniz -[NSString integerValue], -[NSString floatValue]vb Ancak, bunu yapmak için doğru (yerel duyarlı, vs.) yolu kullanmaktır -[NSNumberFormatter numberFromString:]ayarlarını bir NSNumber uygun yerel ayarı dönüştürülmüş vermek ve verilen hangi NSNumberFormattero yüzen izin verip (dahil puan değerleri).


27
+ q Duruma bağlı olarak, yerel ayara duyarlı olmayan doğru yol olabilir.
Thilo

2
Ben dönüştürmek zorunda @"2000"bir etmek intve [@"2000" integerValue]güzel çalıştı ve benim durumumda için biraz daha basittir.
Besi

2
Bu yöntemler arasında büyük performans farklılıkları da vardır.
Tom Andersen

2
bu ARC ile çalışmaz: NSInteger'i NSNumber'a dönüştürmez. Daha fazla kullanmalıyım[NSNumber numberWithInteger ...]
öğrenci

@Thilo ne dedi. "Doğru" ve "yerel ayara duyarlı" eş anlamlıları değildir. Yapılacak doğru şey, sayının ilk başta dizeye nasıl girdiğine bağlıdır. Kullanıcı girdisinden okursanız, yerel duyarlılık istediğiniz şeydir. Başka herhangi bir kaynaktan (yani programlı olarak buraya koyarsanız, bazı harici API'lerden gelen yanıtın bir parçası olarak tüketirsiniz) yerel duyarlı uygun değildir ve hatta yanlış sonuçlar verebilir.
aroth

138

Objective-C

(Not: Bu yöntem, farklı yerel ayarlarla iyi oynatılmaz, ancak a'dan biraz daha hızlıdır NSNumberFormatter)

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

hızlı

Basit ama kirli bir yol

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

Uzatma yolu Bu daha iyi, gerçekten, çünkü yerel ayarlarla ve ondalık sayılarla güzel oynayacak.

extension String {

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

Şimdi şunları yapabilirsiniz:

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

1
Ben dize değerleri büyük miktarda ayrıştırırken profilleme dayalı bunu tercih ederim. Bir NSNumberFormatter yerine bu sözdizimini kullanmak, dizeyi NSNumber'a ayrıştırmak için harcanan zamanın önemli ölçüde azalmasına neden oldu. Ve evet, NSNumberFormatter önbelleğe alındı ​​ve yeniden kullanıldı.
androider

3
bu soru sorulduğunda bu gerçek sözdizimi yoktu. Bugünlerde bunun doğru cevap olduğunu söyleyebilirim.
Chris

1
Kabul ediyorum, ancak diğer bazı ülkelerin ,ve .diğer yolu kullandığını unutmayın (örn 42.000,42. Bir şey floatValuemuhtemelen hesaba
Kevin R

1
Bu burada en güzel çözümdür, ancak ben sadece bir test yaptık ve imzasız hassasiyeti kaybedeceksiniz, bu yüzden İZLEYİN !!!
Stoff81

Benim kullanım durumunda, bir NSString bir NSNumber sözlük anahtarı almak gerekiyordu, bu yüzden @([@"42" intValue])mükemmel çalıştı. Locale için endişelenme.
Chuck Krutsinger

86

, Tamsayılar ile başlayan dizeleri için örneğin @"123", @"456 ft", @"7.89"vb kullanımı -[NSString integerValue].

Yani @([@"12.8 lbs" integerValue])yapmak gibidir [NSNumber numberWithInteger:12].


50

Bunu da yapabilirsiniz:

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

İyi eğlenceler!


26

Tamsayı aldığınızı biliyorsanız şunları kullanabilirsiniz:

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

11

İşte NSNumberFormatter'ın, NSString (xCode 3.2.4, osX 10.6) yerelleştirilmiş numarasını okuyan ve başkalarını uğraştığım saatleri kurtarmak için çalışan bir örnek. Dikkat: Sondaki boşlukları işleyebilirken ("8,765,4" çalışır), bu önde gelen beyaz alanı işleyemez ve başıboş metin karakterlerini işleyemez. (Hatalı giriş dizeleri: "8" ve "8q" ve "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

bu benim için işe yaramıyor. Ben xcode 4.3.2 ile 5.0 için geliştiriyorum. neden herhangi bir fikir?
acecapades

6

Bir dizeyi ikiye dönüştürmek istedim. Yukarıdaki cevap benim için pek işe yaramadı. Ama bu yaptı: Objective-C dize dönüşümleri nasıl?

Hemen hemen tüm yaptığım şuydu:

double myDouble = [myString doubleValue];

Bu NSInteger bir NSNumber dönüştürmez. Bir çifte dönüştürür.
FabKremer

5

Hepinize teşekkürler! Ben kombine geribildirim ve nihayet metin girişi (dize) tamsayı dönüştürmek yönetmek. Ayrıca girişin tamsayı olup olmadığını söyleyebilir :)

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

NSDecimalNumber bunu yapacağını düşünüyorum:

Misal:

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

NSDecimalNumber, NSNumber'ın bir alt sınıfıdır, bu nedenle örtülü döküm yapılmasına izin verilir.


2

C'nin standardı ne olacak atoi?

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

Herhangi bir uyarı olduğunu düşünüyor musunuz?



2

ayrıca bu kodu 8.3.3 ios 10.3 desteği ile de yapabilirsiniz

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

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


0

Bu çok geç biliyorum ama aşağıdaki kod benim için çalışıyor.

Bu kodu deneyin

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

Bu size yardımcı olabilir. Teşekkürler


0

Bunu dene

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

Not - Gereksinimime göre longLongValue kullandım. Gereksiniminize bağlı olarak integerValue, longValue veya başka bir biçimi de kullanabilirsiniz.


-1
extension String {

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

let someFloat = "12.34".numberValue
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.