Chuyển đổi chuỗi thành Float trong Swift


101

Tôi đang cố gắng chuyển đổi các số được lấy từ UITextField, mà tôi cho rằng thực sự là Chuỗi và chuyển đổi chúng thành Float, vì vậy tôi có thể nhân chúng.

Tôi có hai UITextfields được khai báo như sau:

@IBOutlet var wage: UITextField
@IBOutlet var hour: UITextField

Khi người dùng nhấn UIButton, tôi muốn tính tiền lương mà người dùng kiếm được, nhưng tôi không thể, vì trước tiên tôi cần chuyển chúng thành float trước khi có thể sử dụng chúng.

Tôi biết cách chuyển chúng thành số nguyên bằng cách thực hiện điều này:

var wageConversion:Int = 0
wageConversion = wage.text.toInt()!

Tuy nhiên, tôi không biết làm thế nào để chuyển đổi chúng thành float.

Câu trả lời:


200

Swift 2.0+

Bây giờ với Swift 2.0, bạn chỉ có thể sử dụng Float(Wage.text)mà trả về một Float?kiểu. Rõ ràng hơn giải pháp bên dưới mà chỉ trả lại 0.

Nếu bạn muốn một 0giá trị không hợp lệ Floatvì lý do nào đó, bạn có thể sử dụng giá trị Float(Wage.text) ?? 0này sẽ trả về 0nếu nó không hợp lệ Float.


Giải pháp cũ

Cách tốt nhất để xử lý điều này là truyền trực tiếp:

var WageConversion = (Wage.text as NSString).floatValue

Tôi thực sự đã tạo ra một extensionđể sử dụng tốt hơn cái này:

extension String {
    var floatValue: Float {
        return (self as NSString).floatValue
    }
}

Bây giờ bạn có thể chỉ cần gọi var WageConversion = Wage.text.floatValuevà cho phép máy nhánh xử lý thông cầu cho bạn!

Đây là một cách triển khai tốt vì nó có thể xử lý các float thực tế (đầu vào bằng .) và cũng sẽ giúp ngăn người dùng sao chép văn bản vào trường nhập của bạn ( 12p.34hoặc thậm chí 12.12.41).

Rõ ràng, nếu Apple thêm một floatValueSwift vào thì điều này sẽ tạo ra một ngoại lệ, nhưng nó có thể tốt trong thời gian ngắn. Nếu họ thêm nó vào sau đó, thì tất cả những gì bạn cần làm để sửa đổi mã của mình là xóa tiện ích mở rộng và mọi thứ sẽ hoạt động liền mạch, vì bạn đã gọi .floatValuerồi!

Ngoài ra, các biến và hằng số phải bắt đầu bằng chữ thường (bao gồm IBOutlets)


Tiện ích mở rộng không bắt buộc, cầu nối được thực hiện tự động bởi Swift, vì @tom nói rằng tất cả những gì bạn cần là Wage.text.floatValue. Không chắc liệu điều này có thay đổi giữa câu trả lời được đăng và bây giờ hay không, nhưng nó đã ở đó một thời gian.
sketchchyTech

3
@GoodbyeStackOverflow, tôi đang sử dụng Beta 4 và nó chắc chắn không hoạt động. Có lẽ họ đã thay đổi nó trong bản Beta 5? NSStringfloatValuephần mở rộng nhưng Stringkhông. Nhận lỗi:'String' does not have member named floatValue
Firo

Đây có thể là lý do. Ngoài ra, bạn có nhập Foundation ở đầu tệp của mình không?
sketchchyTech

Tôi không coi điều này là an toàn cho lắm, ít nhất là đối với các tiêu chuẩn Swift, vì nếu chuỗi không phải là số, NSString.floatValue sẽ chỉ trả về 0. Điều này sẽ kích hoạt Ngoại lệ hoặc ít nhất là trả về nil.
Ixx

let floatValue = (Float)(Wage.text)... Trong Swift 2.0
TheTiger

23

Bởi vì ở một số nơi trên thế giới, ví dụ, dấu phẩy được sử dụng thay vì số thập phân. Tốt nhất là tạo một NSNumberFormatter để chuyển đổi một chuỗi thành float.

let numberFormatter = NSNumberFormatter()
numberFormatter.numberStyle = NSNumberFormatterStyle.DecimalStyle
let number = numberFormatter.numberFromString(self.stringByTrimmingCharactersInSet(Wage.text))

18

Tôi chuyển đổi String thành Float theo cách này:

let numberFormatter = NSNumberFormatter()
let number = numberFormatter.numberFromString("15.5")
let numberFloatValue = number.floatValue

println("number is \(numberFloatValue)") // prints "number is 15.5"

Tôi nghĩ rằng đây là giải pháp tốt nhất (ít nhất là cho swift 4+), lý do chính là nó trả về một tùy chọn (trái ngược với NSString.floatValue, chỉ trả lại 0nếu có gì đó không ổn.). Lưu ý rằng NSNumberFormatterđã được thay đổi NumberFormatter.
Rôma

9

Cập nhật

Câu trả lời được chấp nhận cho thấy một cách làm mới nhất

Swift 1

Đây là cách Paul Hegarty đã thể hiện trên lớp CS193p của Stanford vào năm 2015:

wageConversion = NSNumberFormatter().numberFromString(wage.text!)!.floatValue

Bạn thậm chí có thể tạo một thuộc tính được tính toán để không phải làm điều đó mọi lúc

var wageValue: Float {
        get {
            return NSNumberFormatter().numberFromString(wage.text!)!.floatValue
        }
        set {
            wage.text = "\(newValue)"
        }
    }

5

Sử dụng giải pháp được chấp nhận, tôi nhận thấy rằng "1.1" của tôi (khi sử dụng chuyển đổi .floatValue) sẽ được chuyển đổi thành 1.10000002384186, không phải là điều tôi muốn. Tuy nhiên, nếu tôi sử dụng .doubleValue thay thế, tôi sẽ nhận được 1.1 mà tôi muốn.

Vì vậy, ví dụ: thay vì sử dụng giải pháp được chấp nhận, tôi đã sử dụng giải pháp này thay thế:

var WageConversion = (Wage.text as NSString).doubleValue

Trong trường hợp của tôi, tôi không cần độ chính xác kép, nhưng sử dụng .floatValue không cho tôi kết quả thích hợp.

Chỉ muốn thêm điều này vào cuộc thảo luận trong trường hợp có người khác gặp phải vấn đề tương tự.


5

Dưới đây sẽ cung cấp cho bạn một Float tùy chọn, dính a! ở cuối nếu bạn biết nó là một Pha nổi, hoặc sử dụng if / let.

let wageConversion = Float(wage.text)

4

Đây là bản điều chỉnh Swift 3 của giải pháp của Paul Hegarty từ câu trả lời của rdprado, với một số kiểm tra cho các tùy chọn được thêm vào nó (trả về 0,0 nếu bất kỳ phần nào của quy trình không thành công):

var wageFloat:Float = 0.0

if let wageText = wage.text {
    if let wageNumber = NumberFormatter().number(from: wageText) {
        wageFloat = wageNumber.floatValue
    }
}

Nhân tiện, tôi đã tham gia lớp CS193p của Stanford bằng iTunes University khi nó vẫn đang dạy Objective-C.

Tôi nhận thấy Paul Hegarty là một người hướng dẫn FANTASTIC và tôi thực sự muốn giới thiệu lớp học cho bất kỳ ai bắt đầu với tư cách là một nhà phát triển iOS trong Swift !!!


1
Đây là câu trả lời đúng duy nhất cho Swift 3 trở lên. Bạn phải sử dụng một NumberFormatterđể xử lý các số dấu phẩy động do người dùng nhập.
rmaddy

3
import Foundation
"-23.67".floatValue // => -23.67

let s = "-23.67" as NSString
s.floatValue // => -23.67

3
Giải thích tại sao mã này hoạt động. Điều này ngăn chặn việc sao chép và dán mà không hiểu về hoạt động của nó.
rayryeng

3

Trong 4 nhanh

let Totalname = "10.0" //Now it is in string

let floatVal  = (Totalname as NSString).floatValue //Now converted to float


1

Bạn có hai tùy chọn khá giống nhau (theo cách tiếp cận và kết quả):

// option 1:
var string_1 : String = "100"
var double_1 : Double = (string_1 as NSString).doubleValue + 99.0

// option 2: 
var string_2 : NSString = "100"
// or:  var string_2 = "100" as NSString
var number_2 : Double = string_2.doubleValue;

2
bridgeToObjectiveC () đã được gỡ bỏ trong bản Beta 5
carmen_munich

1

Double() tạo một Double từ một Int, như thế này:

var convertedDouble = Double(someInt)

Lưu ý rằng điều này sẽ chỉ hoạt động nếu văn bản của bạn thực sự chứa một số. Vì Wagelà trường văn bản, người dùng có thể nhập bất kỳ thứ gì họ muốn và điều này sẽ gây ra lỗi thời gian chạy khi bạn bỏ hộp Tùy chọn được trả về từ đó toInt(). Bạn nên kiểm tra xem chuyển đổi đã thành công chưa trước khi buộc mở hộp.

if let wageInt = Wage.text?.toInt() {
    //we made it in the if so the conversion succeeded.
    var wageConversionDouble = Double(wageInt)
}

Biên tập:

Nếu bạn chắc chắn văn bản sẽ là một số nguyên, bạn có thể làm như sau (lưu ý rằng texttrên UITextField cũng là Tùy chọn)):

if let wageText = Wage.text {
    var wageFloat = Double(wageText.toInt()!)
}

Chà, tôi chỉ cho phép người dùng nhập số vì bàn phím là Bảng thập phân, vì vậy họ thực sự không thể nhập bất kỳ thứ gì khác ngoài số.
Stephen Fox

1
wageConversionFloatsẽ không bao giờ là float, nó sẽ bị treo trực tiếp nếu chuỗi đầu vào là loại float như 234.56. làm thế nào nó có thể là một giải pháp được chấp nhận / ủng hộ ...?
holex

Câu trả lời này không hoạt động nếu văn bản chứa giá trị thập phân. Ví dụ - câu trả lời này sẽ trả về 3nếu trường văn bản có 3.5. Điều này là do văn bản đầu tiên được chuyển đổi thành một Int, sau đó Intđược chuyển đổi thành a Float.
rmaddy

1
@StephenFox Hãy nhớ rằng người dùng có thể dán văn bản không phải số vào trường văn bản hoặc người dùng có thể có bàn phím bên ngoài. Không bao giờ chỉ dựa vào bàn phím để đảm bảo nhập dữ liệu.
rmaddy

thực sự nó hoạt động, với các số nguyên, không chỉ số thập phân. một số thập phân sẽ tạo ra một lỗi nghiêm trọng!
Miles Works

1

Tôi đã tìm thấy một cách khác để lấy giá trị đầu vào của UITextField và truyền nó vào một float:

    var tempString:String?
    var myFloat:Float?

    @IBAction func ButtonWasClicked(_ sender: Any) {
       tempString = myUITextField.text
       myFloat = Float(tempString!)!
    }

1

bạn có thể dùng,

let wg = Float(wage.text!)

Nếu bạn muốn làm tròn số float thành 2 chữ số thập phân:

let wg = Float(String(format: "%.2f",wage.text!)

0

Đây là cách tôi tiếp cận nó. Tôi không muốn "qua cầu", vì dù sao nó cũng đã bị xóa khỏi Xcode 6 beta 5, nhanh chóng và bẩn thỉu:

extension String {

    // converting a string to double
    func toDouble() -> Double? {

        // split the string into components
        var comps = self.componentsSeparatedByString(".")

        // we have nothing
        if comps.count == 0 {
            return nil
        }
        // if there is more than one decimal
        else if comps.count > 2 {
            return nil
        }
        else if comps[0] == "" || comps[1] == "" {
            return nil
        }

        // grab the whole portion
        var whole = 0.0
        // ensure we have a number for the whole
        if let w = comps[0].toInt() {
            whole = Double(w)
        }
        else {
            return nil
        }

        // we only got the whole
        if comps.count == 1 {

            return whole

        }

        // grab the fractional
        var fractional = 0.0
        // ensure we have a number for the fractional
        if let f = comps[1].toInt() {

            // use number of digits to get the power
            var toThePower = Double(countElements(comps[1]))

            // compute the fractional portion
            fractional = Double(f) / pow(10.0, toThePower)

        }
        else {
            return nil
        }

        // return the result
        return whole + fractional
    }

    // converting a string to float
    func toFloat() -> Float? {

        if let val = self.toDouble() {
            return Float(val)
        }
        else {
            return nil
        }

    }

}


// test it out
var str = "78.001"

if let val = str.toFloat() {
    println("Str in float: \(val)")
}
else {
    println("Unable to convert Str to float")
}

// now in double
if let val = str.toDouble() {
    println("Str in double: \(val)")
}
else {
    println("Unable to convert Str to double")
}

1
Bởi vì ở một số nơi trên thế giới, ví dụ, dấu phẩy được sử dụng thay vì số thập phân. Tốt nhất là tạo một NSNumberFormatter để chuyển đổi một chuỗi thành float. Nhìn vào @DmitriFuerle Answer
carmen_munich

@PartiallyFrozenOJ Bạn đã thử toDouble()hàm với chuỗi "10" Ý tôi là nếu không có số thập phân. Nó sẽ sụp đổ bằng mọi cách. Bởi vì trong trường hợp đó, số lượng sẽ là 1 và bạn không xử lý điều đó. Nó sẽ sụp đổ lúc else if comps[0] == "" || comps[1] == "". Dù sao bạn rất nghiêm túc trong việc chuyển đổi.
TheTiger

@PartiallyFrozenOJ Nhưng nếu điều kiện cũng giống như năm 2014. Dù sao Không có vấn đề!
TheTiger

0

Vì lợi ích của sự hoàn chỉnh, đây là một giải pháp sử dụng một phần mở rộng UITextFieldcũng có thể xem xét một ngôn ngữ khác.

Đối với Swift 3+

extension UITextField {
    func floatValue(locale : Locale = Locale.current) -> Float {
        let numberFormatter = NumberFormatter()
        numberFormatter.numberStyle = .decimal
        numberFormatter.locale = locale

        let nsNumber = numberFormatter.number(from: text!)
        return nsNumber == nil ? 0.0 : nsNumber!.floatValue
    }
}

Như một giải pháp chung, điều này có thể sẽ trả về một Float?và không coi các giá trị không hợp lệ là 0.0. Hãy để người gọi làm điều gì đó giống như let val = field.floatValue ?? 0.0nếu một trường hợp nhất định sẽ coi kết quả xấu là 0.
rmaddy

0

Swift 4/5, chỉ sử dụng Float (giá trị).

let string_value : String = "123200"

let float_value : Float = Float(string_value)

print(float_value)

Trả lời: 123200


-1

Dùng cái này:

 // get the values from text boxes
    let a:Double = firstText.text.bridgeToObjectiveC().doubleValue
    let b:Double = secondText.text.bridgeToObjectiveC().doubleValue

//  we checking against 0.0, because above function return 0.0 if it gets failed to convert
    if (a != 0.0) && (b != 0.0) {
        var ans = a + b
        answerLabel.text = "Answer is \(ans)"
    } else {
        answerLabel.text = "Input values are not numberic"
    }

1
bridgeToObjectiveC () đã bị xóa trong bản Beta 5
carmen_munich

-4

Cách dễ dàng:

// toInt returns optional that's why we used a:Int?
let a:Int? = firstText.text.toInt()
let b:Int? = secondText.text.toInt()

// check a and b before unwrapping using !
if a && b {
    var ans = a! + b!
    answerLabel.text = "Answer is \(ans)"
} else {
    answerLabel.text = "Input values are not numberic"
}

bạn có thể sử dụng phương pháp tương tự cho các tính toán khác, hy vọng điều này sẽ giúp !!


3
Như tuyệt vời như thế này được, ông đã yêu cầufloat
Jack
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.