วิธีการแปลง NSString เป็น NSNumber


569

ฉันสามารถแปลงNSStringที่มีจำนวนชนิดของข้อมูลใด ๆ ดั้งเดิม (เช่นint, float, char, unsigned intฯลฯ )? ปัญหาคือฉันไม่ทราบว่าหมายเลขชนิดใดที่สตริงจะมีเวลารันไทม์

ฉันมีความคิดว่าจะทำอย่างไร แต่ฉันไม่แน่ใจว่าสิ่งนี้ใช้ได้กับทุกประเภทหรือไม่และยังไม่ได้ลงนามและค่าจุดลอยตัว:

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

ขอบคุณสำหรับความช่วยเหลือ

คำตอบ:


1245

ใช้NSNumberFormatter:

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

หากสายไม่ได้เป็นตัวเลขที่ถูกต้องแล้วจะmyNumber nilถ้าเป็นตัวเลขที่ถูกต้องคุณก็จะได้NSNumberตัวเลขที่เป็นจริง


16
สำหรับผู้ที่ดูเหมือนจะไม่ทำงาน: ตรวจสอบว่าเกี่ยวข้องกับสถานที่ของคุณหรือไม่ NSNumberFormatter (เท่าที่ฉันรู้) โดยค่าเริ่มต้นจะใช้ตำแหน่งที่ตั้งของสหรัฐอเมริกานั่นคือคาดว่าตัวคั่นทศนิยมจะเป็น "" ตัวละคร หากคุณใช้ "," เพื่อแยกเศษส่วนคุณอาจต้องบอกให้ฟอร์แมตเตอร์ใช้ภาษาปัจจุบันของคุณ: [f setLocale: [NSLocale currentLocale]];
pille

2
@pille โดยค่าเริ่มต้นสถานที่คือ+currentLocaleแต่คุณถูกต้อง; เราต้องพิจารณาสถานที่เมื่อต้องจัดการกับการแปลงสิ่งต่าง ๆ เป็นรูปแบบที่มนุษย์อ่านได้
เดฟ DeLong

คุณพบว่าที่ไหนเป็น currentLocale ตามค่าเริ่มต้น ฉันสามารถยืนยันได้ว่า numberFromString ใช้เครื่องหมายจุดแม้ในโทรศัพท์ฝรั่งเศสที่ใช้เครื่องหมายจุลภาค ฉันสามารถยืนยันได้ว่าโดยค่าเริ่มต้นเมื่อคุณส่งออกจำนวนก็จะใช้สถานที่ปัจจุบันโดยค่าเริ่มต้น
allaire

แต่ถ้าสตริงสามารถมี int หรือลอยได้
GeneCode

179

คุณสามารถใช้-[NSString integerValue]และ-[NSString floatValue]อื่น ๆ อย่างไรก็ตามวิธีที่ถูกต้อง (ความไวต่อสถานที่ ฯลฯ ) การทำเช่นนี้คือการใช้-[NSNumberFormatter numberFromString:]ซึ่งจะทำให้คุณมี NSNumber แปลงจากสถานที่ที่เหมาะสมและได้รับการตั้งค่าของNSNumberFormatter(รวมถึงว่าจะอนุญาตให้ลอย ค่าจุด)


27
+ q ขึ้นอยู่กับสถานการณ์ที่ไม่ได้คำนึงถึงสถานที่จริงอาจเป็นวิธีที่ถูกต้อง
Thilo

2
ฉันต้องเปลี่ยน@"2000"เป็นintและ[@"2000" integerValue]ทำงานได้ดีและค่อนข้างง่ายสำหรับกรณีของฉัน
Besi

2
นอกจากนี้ยังมีความแตกต่างด้านประสิทธิภาพอย่างมากระหว่างวิธีการเหล่านี้
Tom Andersen

2
สิ่งนี้ใช้ไม่ได้กับ ARC: มันจะไม่แปลง NSInteger เป็น NSNumber ฉันต้องใช้ต่อไป[NSNumber numberWithInteger ...]
ผู้เรียน

@Thilo พูดอะไร "ถูกต้อง" และ "มีความอ่อนไหวต่อโลแคล" ไม่ใช่คำพ้องความหมาย สิ่งที่ถูกต้องที่จะทำจริงขึ้นอยู่กับจำนวนที่ได้รับในสายแรก หากคุณอ่านจากอินพุตของผู้ใช้งาน Local-sensitive คือสิ่งที่คุณต้องการ จากแหล่งอื่น ๆ (เช่นคุณใส่ไว้ที่นั่นโดยทางโปรแกรมคุณกำลังบริโภคมันเป็นส่วนหนึ่งของการตอบสนองจาก API ภายนอกบางตัว ฯลฯ ) การคำนึงถึงท้องถิ่นไม่เหมาะสมและอาจให้ผลลัพธ์ที่ไม่ถูกต้อง
aroth

138

Objective-C

(หมายเหตุ: วิธีนี้เล่นได้ไม่ดีกับภาษาที่แตกต่าง แต่เร็วกว่า a NSNumberFormatter)

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

รวดเร็ว

เรียบง่าย แต่สกปรก

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

ส่วนต่อขยายทาง นี้ดีกว่าจริง ๆ เพราะจะเล่นได้ดีกับสถานที่และทศนิยม

extension String {

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

ตอนนี้คุณสามารถทำได้:

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

1
ฉันชอบสิ่งนี้โดยพิจารณาจากการทำโปรไฟล์เมื่อฉันแยกวิเคราะห์ค่าสตริงจำนวนมาก การใช้ไวยากรณ์นี้ค่อนข้างจะทำให้ NSNumberFormatter นำไปสู่การลดความสำคัญในเวลาที่ใช้ในการแยกสตริงเพื่อ NSNumber และใช่ NSNumberFormatter ถูกแคชและนำกลับมาใช้ใหม่
androider

3
ไวยากรณ์ตามตัวอักษรนี้ไม่มีอยู่เมื่อมีการถามคำถามนี้ ฉันว่านี่เป็นคำตอบที่ถูกต้องทุกวันนี้
คริส

1
ฉันเห็นด้วย แต่โปรดทราบว่าบางประเทศใช้,และ.วิธีอื่น ๆ (เช่น42.000,42บางสิ่งบางอย่างfloatValueอาจไม่ได้บัญชีใช่หรือไม่
Kevin R

1
นี่เป็นทางออกที่ดีที่สุดที่นี่ แต่ฉันเพิ่งจะทำการทดสอบและคุณจะสูญเสียความแม่นยำที่ไม่ได้ลงชื่อดังนั้นระวัง !!!
Stoff81

ในกรณีที่ใช้งานของฉันฉันต้องได้รับคีย์พจนานุกรม NSNumber จาก NSString ดังนั้น@([@"42" intValue])ทำงานได้อย่างสมบูรณ์ ไม่ต้องกังวลเกี่ยวกับสถานที่เกิดเหตุ
Chuck Krutsinger

86

สำหรับสตริงเริ่มต้นด้วยจำนวนเต็มเช่น@"123", @"456 ft", @"7.89"ฯลฯ -[NSString integerValue]การใช้งาน

ดังนั้นเป็นเหมือนการทำ@([@"12.8 lbs" integerValue])[NSNumber numberWithInteger:12]



26

หากคุณรู้ว่าคุณได้รับจำนวนเต็มคุณสามารถใช้:

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

11

นี่คือตัวอย่างการทำงานของ NSNumberFormatter อ่านหมายเลขที่แปลเป็นภาษาท้องถิ่น NSString (xCode 3.2.4, osX 10.6) เพื่อประหยัดเวลาอื่น ๆ ที่ฉันเพิ่งทำไป ระวัง: ในขณะที่สามารถจัดการกับช่องว่างต่อท้าย ("8,765.4" งาน) นี้ไม่สามารถจัดการกับพื้นที่สีขาวชั้นนำและสิ่งนี้ไม่สามารถจัดการกับตัวอักษรข้อความหลงทาง (สตริงอินพุตไม่ถูกต้อง: "8" และ "8q" และ "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

มันไม่ได้ผลสำหรับฉัน ฉันกำลังพัฒนา 5.0 พร้อม xcode 4.3.2 ความคิดใด ๆ ว่าทำไม?
acecapades

6

ฉันต้องการแปลงสตริงเป็นสองเท่า คำตอบข้างต้นนี้ไม่ได้ผลสำหรับฉัน แต่สิ่งนี้ทำ: จะทำการแปลงสตริงใน Objective-C ได้อย่างไร

ทั้งหมดที่ฉันทำก็คือ:

double myDouble = [myString doubleValue];

สิ่งนี้ไม่แปลง NSInteger เป็น NSNumber มันแปลงเป็นสองเท่า
FabKremer

5

ขอบคุณทุกคน! ฉันรวมข้อเสนอแนะและในที่สุดก็จัดการแปลงจากการป้อนข้อความ (สตริง) เป็นจำนวนเต็ม รวมทั้งสามารถบอกได้ว่าอินพุตเป็นจำนวนเต็มหรือไม่ :)

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 จะทำ:

ตัวอย่าง:

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

NSDecimalNumber เป็น subclass ของ NSNumber ดังนั้นอนุญาตให้ใช้การแคสต์โดยนัย







0

ฉันรู้ว่ามันสายเกินไป

ลองรหัสนี้

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

สิ่งนี้อาจช่วยคุณได้ ขอบคุณ


0

ลองสิ่งนี้

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

หมายเหตุ - ฉันใช้ longLongValue ตามความต้องการของฉันแล้ว คุณยังสามารถใช้ integerValue, longValue หรือรูปแบบอื่น ๆ ตามความต้องการของคุณ


-1
extension String {

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

let someFloat = "12.34".numberValue
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.