Ubah String menjadi Float di Swift

101

Saya mencoba mengonversi angka yang diambil dari UITextField, yang saya anggap, sebenarnya adalah Strings, dan mengubahnya menjadi Float, jadi saya bisa mengalikannya.

Saya memiliki dua UITextfields yang dinyatakan sebagai berikut:

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

Ketika pengguna menekan tombol UIButton, saya ingin menghitung gaji yang diperoleh pengguna, tetapi saya tidak bisa, karena saya harus mengubahnya menjadi float terlebih dahulu, sebelum saya dapat menggunakannya.

Saya tahu cara mengonversinya menjadi integer dengan melakukan ini:

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

Namun, saya tidak tahu bagaimana mengubahnya menjadi float.

Stephen Fox
sumber

Jawaban:

200

Swift 2.0+

Sekarang dengan Swift 2.0 Anda bisa menggunakan Float(Wage.text)yang mengembalikan sebuah Float?tipe. Lebih jelas daripada solusi di bawah ini yang baru saja kembali 0.

Jika Anda ingin 0nilai yang tidak valid Floatkarena alasan tertentu, Anda dapat menggunakan Float(Wage.text) ?? 0yang akan dikembalikan 0jika tidak valid Float.


Solusi Lama

Cara terbaik untuk menanganinya adalah transmisi langsung:

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

Saya sebenarnya membuat extensionuntuk menggunakan ini dengan lebih baik juga:

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

Sekarang Anda bisa memanggil var WageConversion = Wage.text.floatValuedan mengizinkan ekstensi untuk menangani jembatan untuk Anda!

Ini adalah implementasi yang baik karena dapat menangani float aktual (masukan dengan .) dan juga akan membantu mencegah pengguna menyalin teks ke kolom masukan Anda ( 12p.34, atau bahkan 12.12.41).

Jelas, jika Apple menambahkan a floatValueke Swift ini akan menimbulkan pengecualian, tetapi mungkin bagus untuk sementara waktu. Jika mereka menambahkannya nanti, maka yang perlu Anda lakukan untuk mengubah kode Anda adalah menghapus ekstensi dan semuanya akan bekerja dengan lancar, karena Anda sudah akan menelepon .floatValue!

Selain itu, variabel dan konstanta harus dimulai dengan huruf kecil (termasuk IBOutlets)

Firo
sumber
Ekstensi tidak diperlukan, penghubung dilakukan secara otomatis oleh Swift, karena @tom menyatakan yang Anda butuhkan hanyalah Wage.text.floatValue. Tidak yakin apakah ini berubah antara jawaban yang diposting dan sekarang, tapi sudah ada untuk sementara waktu.
sketchyTech
3
@GoodbyeStackOverflow, saya menggunakan Beta 4 dan pasti tidak berhasil. Mungkin mereka mengubahnya di Beta 5? NSStringmemiliki floatValueekstensi tetapi Stringtidak. Dapatkan kesalahan:'String' does not have member named floatValue
Firo
Ini mungkin alasannya. Selain itu, apakah Anda telah mengimpor Foundation di bagian atas file Anda?
sketchyTech
Saya tidak menganggap ini sangat aman, setidaknya untuk standar Swift, karena jika stringnya bukan angka, NSString.floatValue hanya mengembalikan 0. Ini harus memicu Pengecualian atau setidaknya mengembalikan nihil.
Ixx
let floatValue = (Float)(Wage.text)... Dalam Swift 2.0
TheTiger
23

Karena di beberapa bagian dunia, misalnya, koma digunakan sebagai pengganti desimal. Cara terbaik adalah membuat NSNumberFormatter untuk mengonversi string menjadi float.

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

Saya mengonversi String ke Float dengan cara ini:

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

println("number is \(numberFloatValue)") // prints "number is 15.5"
Mert
sumber
Saya pikir ini adalah solusi terbaik (setidaknya untuk 4+ cepat), alasan utamanya adalah ia mengembalikan opsional (sebagai lawan NSString.floatValue, yang hanya mengembalikan 0jika ada yang salah.). Perhatikan bahwa NSNumberFormattertelah diubah NumberFormatter.
Rom
9

Memperbarui

Jawaban yang diterima menunjukkan cara melakukan yang lebih mutakhir

Cepat 1

Inilah yang ditunjukkan Paul Hegarty di kelas CS193p Stanford pada tahun 2015:

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

Anda bahkan dapat membuat properti yang dihitung karena tidak harus melakukannya setiap saat

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

Dengan menggunakan solusi yang diterima, saya menemukan bahwa "1.1" saya (saat menggunakan konversi .floatValue) akan dikonversi ke 1.10000002384186, yang bukan itu yang saya inginkan. Namun, jika saya menggunakan .doubleValue sebagai gantinya, saya akan mendapatkan 1.1 yang saya inginkan.

Jadi misalnya, alih-alih menggunakan solusi yang diterima, saya menggunakan ini sebagai gantinya:

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

Dalam kasus saya, saya tidak memerlukan presisi ganda, tetapi menggunakan .floatValue tidak memberi saya hasil yang sesuai.

Hanya ingin menambahkan ini ke diskusi kalau-kalau ada orang lain yang mengalami masalah yang sama.

Yjo-jo
sumber
5

Di bawah ini akan memberi Anda Float opsional, tetap a! di akhir jika Anda tahu itu menjadi Float, atau gunakan jika / biarkan.

let wageConversion = Float(wage.text)
bandejapaisa
sumber
4

Berikut adalah adaptasi Swift 3 dari solusi Paul Hegarty dari jawaban rdprado, dengan beberapa pemeriksaan opsional yang ditambahkan padanya (mengembalikan 0.0 jika ada bagian dari proses yang gagal):

var wageFloat:Float = 0.0

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

Ngomong-ngomong, saya mengambil kelas CS193p Stanford menggunakan iTunes University saat masih mengajar Objective-C.

Saya menemukan Paul Hegarty sebagai instruktur FANTASTIS, dan saya akan sangat merekomendasikan kelas ini kepada siapa pun yang memulai sebagai pengembang iOS di Swift !!!

Carl Smith
sumber
1
Ini adalah satu-satunya jawaban yang benar untuk Swift 3 atau yang lebih baru. Anda harus menggunakan NumberFormatteruntuk menangani pengguna yang memasukkan angka floating point.
rmaddy
3
import Foundation
"-23.67".floatValue // => -23.67

let s = "-23.67" as NSString
s.floatValue // => -23.67
tom
sumber
3
Jelaskan mengapa kode ini berfungsi. Ini mencegah penyalinan dan penempelan tanpa memahami operasinya.
rayryeng
3

Dengan cepat 4

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

let floatVal  = (Totalname as NSString).floatValue //Now converted to float
Raghib Arshi
sumber
3
extension String {    
    func floatValue() -> Float? {
        return Float(self)
    }
}
FlowUI. SimpleUITesting.com
sumber
1
kenapa tidak begitu saja return Float(self)?
Leo Dabus
1

Anda memiliki dua opsi yang sangat mirip (berdasarkan pendekatan dan hasil):

// 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;
Michael Dorner
sumber
2
bridgeToObjectiveC () telah dihapus di Beta 5
carmen_munich
1

Double() membangun Double dari Int, seperti ini:

var convertedDouble = Double(someInt)

Perhatikan bahwa ini hanya akan berfungsi jika teks Anda benar-benar berisi angka. Karena Wagemerupakan bidang teks, pengguna dapat memasukkan apa pun yang mereka inginkan dan ini akan memicu kesalahan waktu proses saat Anda membuka kotak Opsional yang dikembalikan dari toInt(). Anda harus memeriksa apakah konversi berhasil sebelum memaksa unboxing.

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

Edit:

Jika Anda yakin teksnya adalah bilangan bulat, Anda dapat melakukan sesuatu seperti ini (perhatikan bahwa textdi UITextField juga Opsional)):

if let wageText = Wage.text {
    var wageFloat = Double(wageText.toInt()!)
}
Tombak
sumber
Saya hanya mengizinkan pengguna untuk memasukkan angka karena papan tombolnya adalah Papan Desimal, jadi mereka tidak dapat memasukkan apa pun selain angka.
Stephen Fox
1
wageConversionFloattidak akan pernah menjadi float, itu crash secara langsung jika string input adalah semacam float 234.56. bagaimana itu bisa menjadi solusi yang diterima / disukai ...?
holex
Jawaban ini tidak berfungsi jika teks berisi nilai desimal. Contoh - jawaban ini akan ditampilkan 3jika kolom teks memiliki 3.5. Ini karena teks pertama-tama diubah menjadi Int, kemudian Intdiubah menjadi Float.
rmaddy
1
@StephenFox Perlu diingat bahwa pengguna dapat menempelkan teks non-numerik ke dalam bidang teks atau pengguna mungkin memiliki keyboard eksternal. Jangan hanya mengandalkan keyboard untuk memastikan entri data.
rmaddy
sebenarnya itu berfungsi, dengan bilangan bulat, hanya saja bukan desimal. desimal akan menghasilkan kesalahan fatal!
Miles Works
1

Saya menemukan cara lain untuk mengambil nilai input dari UITextField dan melemparkannya ke float:

    var tempString:String?
    var myFloat:Float?

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

kamu bisa memakai,

let wg = Float(wage.text!)

Jika Anda ingin membulatkan pelampung ke 2 tempat desimal:

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

Beginilah cara saya mendekatinya. Saya tidak ingin "menyeberangi jembatan", karena itu telah dihapus dari Xcode 6 beta 5, cepat dan kotor:

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")
}
xBACP
sumber
1
Karena di beberapa bagian dunia, misalnya, koma digunakan sebagai pengganti desimal. Cara terbaik adalah membuat NSNumberFormatter untuk mengonversi string menjadi float. Lihatlah Jawaban @DmitriFuerle
carmen_munich
@ ParsiallyF FrozenOJ Sudahkah Anda mencoba toDouble()fungsi dengan string "10" maksud saya jika tidak ada desimal. Ini akan macet juga. Karena dalam kasus itu hitungannya akan menjadi 1 dan Anda tidak menanganinya. Ini akan crash pada else if comps[0] == "" || comps[1] == "". Bagaimanapun Anda begitu serius dalam pertobatan.
TheTiger
@Bekas_Kalau_Kalau kondisinya sama di tahun 2014 juga. Pokoknya Tidak masalah!
TheTiger
0

Demi kelengkapan, ini adalah solusi yang menggunakan ekstensi UITextFieldyang juga dapat mempertimbangkan lokasi yang berbeda.

Untuk 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
    }
}
vadian
sumber
Sebagai solusi umum, ini mungkin mengembalikan a Float?dan tidak memperlakukan nilai yang tidak valid sebagai 0.0. Biarkan pemanggil melakukan sesuatu seperti let val = field.floatValue ?? 0.0jika kasus tertentu memperlakukan hasil buruk sebagai nol.
rmaddy
0

Swift 4/5, gunakan hanya Float (nilai).

let string_value : String = "123200"

let float_value : Float = Float(string_value)

print(float_value)

Jawaban: 123200

Krunal Patel
sumber
-1

Gunakan ini:

 // 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"
    }
Narendar Singh Saini
sumber
1
bridgeToObjectiveC () telah dihapus di Beta 5
carmen_munich
-4

Jalan mudah:

// 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"
}

Anda dapat menggunakan pendekatan yang sama untuk perhitungan lain, semoga bantuan ini !!

Narendar Singh Saini
sumber
3
Sehebat ini, dia memintafloat
Jack