Cách chuyển đổi NSString thành NSNumber


569

Làm thế nào tôi có thể chuyển đổi một NSStringchứa một số bất kỳ kiểu dữ liệu cơ bản (ví dụ như int, float, char, unsigned int, vv)? Vấn đề là, tôi không biết loại chuỗi nào sẽ chứa trong thời gian chạy.

Tôi có một ý tưởng làm thế nào để làm điều đó, nhưng tôi không chắc liệu nó có hoạt động với bất kỳ loại nào không, cũng không có giá trị và dấu phẩy động:

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

Cảm ơn đã giúp đỡ.

Câu trả lời:


1245

Sử dụng một NSNumberFormatter:

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

Nếu chuỗi không phải là một số hợp lệ, thì myNumbersẽ là nil. Nếu đó là một số hợp lệ, thì bây giờ bạn có tất cả những NSNumberđiều tốt đẹp để tìm ra nó thực sự là loại số nào.


16
Đối với những người dường như không hoạt động: Kiểm tra xem nó có liên quan đến địa phương của bạn không. NSNumberFormatter (theo như tôi biết) theo mặc định sử dụng ngôn ngữ Hoa Kỳ, tức là mong muốn dấu tách thập phân là "." tính cách. Nếu bạn sử dụng "," để phân tách phân số, bạn có thể cần nói cho bộ định dạng sử dụng ngôn ngữ hiện tại của bạn: [f setLocale: [NSLocale currentLocale]];
pille

2
@pille theo mặc định miền địa phương là +currentLocale, nhưng bạn đã đúng; người ta phải luôn luôn xem xét ngôn ngữ khi xử lý các công cụ chuyển đổi thành dạng có thể đọc được.
Dave DeLong

Bạn đã thấy rằng nó là currentLocale theo mặc định ở đâu? Tôi có thể xác nhận rằng numberFromString đang sử dụng ký hiệu dấu chấm ngay cả trên điện thoại của Pháp nơi sử dụng dấu phẩy. Tôi có thể xác nhận rằng theo mặc định, khi bạn xuất một số, nó sử dụng ngôn ngữ hiện tại theo mặc định
allaire

Nhưng nếu chuỗi có thể chứa int hoặc float thì sao?
GeneCode

179

Bạn có thể sử dụng -[NSString integerValue], -[NSString floatValue]v.v. Tuy nhiên, cách chính xác (nhạy cảm với ngôn ngữ, v.v.) để làm điều này là sử dụng -[NSNumberFormatter numberFromString:]nó sẽ cung cấp cho bạn một NSNumber được chuyển đổi từ ngôn ngữ thích hợp và đưa ra các cài đặt của NSNumberFormatter(bao gồm cả liệu nó có cho phép nổi không giá trị điểm).


27
+ q Tùy thuộc vào tình huống, không nhạy cảm địa phương thực sự có thể là cách chính xác.
Thilo

2
Tôi đã phải chuyển đổi @"2000"sang một int[@"2000" integerValue]làm việc độc đáo và đơn giản hơn một chút cho trường hợp của tôi.
Besi

2
Ngoài ra còn có sự khác biệt hiệu suất rất lớn giữa các phương pháp này.
Tom Andersen

2
điều này không hoạt động với ARC: nó sẽ không chuyển đổi NSInteger thành NSNumber. Tôi phải tiếp tục sử dụng[NSNumber numberWithInteger ...]
người học

Những gì @Thilo nói. "Chính xác" và "nhạy cảm địa phương" không phải là từ đồng nghĩa. Điều chính xác cần làm thực sự phụ thuộc vào cách số đã vào chuỗi ở vị trí đầu tiên. Nếu bạn đọc nó từ đầu vào của người dùng, thì nhạy cảm cục bộ là những gì bạn muốn. Từ bất kỳ nguồn nào khác (tức là bạn đặt nó ở đó theo lập trình, bạn đang sử dụng nó như một phần của phản hồi từ một số API bên ngoài, v.v.) nhạy cảm cục bộ là không phù hợp và thậm chí có thể cho kết quả không chính xác.
aroth

138

Mục tiêu-C

(Lưu ý: phương pháp này không chơi tốt với các địa điểm khác nhau, nhưng nhanh hơn một chút NSNumberFormatter)

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

Nhanh

Cách đơn giản nhưng bẩn thỉu

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

Cách mở rộng Điều này tốt hơn, thực sự, bởi vì nó sẽ chơi độc đáo với các địa phương và số thập phân.

extension String {

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

Bây giờ bạn có thể chỉ cần làm:

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

1
Tôi thích điều này dựa trên hồ sơ khi tôi phân tích một lượng lớn các giá trị chuỗi. Việc sử dụng cú pháp này thay vào đó là NSNumberFormatter đã giúp giảm đáng kể thời gian phân tích chuỗi thành NSNumber. Và vâng, NSNumberFormatter đã được lưu trữ và sử dụng lại.
androider

3
cú pháp nghĩa đen này không tồn tại khi câu hỏi này được hỏi. Tôi muốn nói rằng đây là câu trả lời chính xác ngày nay.
Chris

1
Tôi đồng ý, nhưng làm lưu ý rằng một số quốc gia khác sử dụng ,.xung quanh cách khác (ví dụ như 42.000,42cái gì đó. floatValueCó lẽ không chiếm?
Kevin R

1
Đây là giải pháp tốt nhất ở đây, tuy nhiên tôi mới chạy thử nghiệm và bạn sẽ mất độ chính xác không dấu nên HÃY XEM RA !!!
Stoff81

Trong trường hợp sử dụng của tôi, tôi cần lấy khóa từ điển NSNumber từ NSString, để @([@"42" intValue])hoạt động hoàn hảo. Không lo lắng về Locale.
Chuck Krutsinger

86

Đối với chuỗi bắt đầu với số nguyên, ví dụ @"123", @"456 ft", @"7.89"vv, sử dụng-[NSString integerValue] .

Vì vậy, @([@"12.8 lbs" integerValue])giống như làm [NSNumber numberWithInteger:12].


50

Bạn cũng có thể làm điều này:

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

Chúc vui vẻ!


26

Nếu bạn biết rằng bạn nhận được số nguyên, bạn có thể sử dụng:

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

11

Đây là một mẫu hoạt động của NSNumberFormatter đọc số NSString được bản địa hóa (xCode 3.2.4, osX 10.6), để tiết kiệm cho người khác những giờ tôi vừa trải qua. Chú ý: trong khi nó có thể xử lý các khoảng trống theo dõi ("8,765,4" hoạt động), điều này không thể xử lý khoảng trắng hàng đầu và điều này không thể xử lý các ký tự văn bản đi lạc. (Chuỗi đầu vào xấu: "8" và "8q" và "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

điều này không làm việc cho tôi. Tôi đang phát triển 5.0 với xcode 4.3.2. bất cứ ý tưởng tại sao?
acecapades


5

Cảm ơn tất cả! Tôi kết hợp phản hồi và cuối cùng quản lý để chuyển đổi từ nhập văn bản (chuỗi) sang Integer. Thêm vào đó, nó có thể cho tôi biết liệu đầu vào là số nguyên :)

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

Tôi nghĩ NSDecimalNumber sẽ làm điều đó:

Thí dụ:

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

NSDecimalNumber là một lớp con của NSNumber, do đó, việc truyền ẩn cho phép.


2

Tiêu chuẩn của C thì atoisao?

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

Bạn có nghĩ rằng có bất kỳ cảnh báo?



2

bạn cũng có thể làm như mã này hỗ trợ 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

Tôi biết điều này là rất muộn nhưng dưới đây mã đang làm việc cho tôi.

Hãy thử mã này

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

Điều này có thể giúp bạn. Cảm ơn


0

Thử cái này

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

Lưu ý - Tôi đã sử dụng longLongValue theo yêu cầu của tôi. Bạn cũng có thể sử dụng số nguyênValue, longValue hoặc bất kỳ định dạng nào khác tùy theo yêu cầu của bạn.


-1
extension String {

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

let someFloat = "12.34".numberValue
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.