Swift'de String'i Float'a Dönüştür


101

Bir UITextField'den alınan sayıların aslında Strings olduğunu ve onları Float'a dönüştürdüğünü düşündüğüm sayıları dönüştürmeye çalışıyorum, böylece onları çarpabilirim.

UITextfieldAşağıdaki gibi beyan edilen iki s var :

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

Kullanıcı bir UIB düğmesine bastığında, kullanıcının kazandığı ücreti hesaplamak istiyorum, ancak kullanmadan önce onları floatlara çevirmem gerektiğinden yapamıyorum.

Bunu yaparak onları tam sayıya nasıl dönüştüreceğimi biliyorum:

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

Ancak, onları şamandıralara nasıl dönüştüreceğim hakkında hiçbir fikrim yok.

Yanıtlar:


200

Swift 2.0+

Şimdi Swift 2.0 ile sadece Float(Wage.text)bir Float?tür döndüren kullanabilirsiniz . Sadece geri dönen aşağıdaki çözümden daha net 0.

Herhangi bir nedenle 0geçersiz bir değer Floatistiyorsanız, geçerli değilse Float(Wage.text) ?? 0dönecek olanı kullanabilirsiniz .0Float


Eski Çözüm

Bunu halletmenin en iyi yolu doğrudan yayın yapmaktır:

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

Aslında extensionbunu da daha iyi kullanmak için bir yarattım :

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

Artık arayıp var WageConversion = Wage.text.floatValueuzantının sizin için köprüyü kaldırmasına izin verebilirsiniz!

Bu, gerçek kayan değerleri (ile giriş .) işleyebildiğinden ve ayrıca kullanıcının girdi alanınıza ( 12p.34veya hatta 12.12.41) metin kopyalamasını önlemeye yardımcı olduğundan iyi bir uygulamadır .

Açıkçası, Apple floatValueSwift'e bir ekleme yaparsa, bu bir istisna yaratacaktır, ancak bu arada güzel olabilir. Daha sonra eklerlerse, kodunuzu değiştirmek için yapmanız gereken tek şey uzantıyı kaldırmaktır ve zaten arayacağınız için her şey sorunsuz çalışacaktır .floatValue!

Ayrıca değişkenler ve sabitler küçük harfle başlamalıdır (dahil IBOutlets)


Uzantı gerekmez, köprü Swift tarafından otomatik olarak yapılır, çünkü @tom ihtiyacınız olan tek şeyin Wage.text.floatValue olduğunu belirtir. Bunun gönderilen cevapla şimdi arasında değişip değişmediğinden emin değilim, ancak bir süredir oradaydı.
sketchyTech

3
@GoodbyeStackOverflow, Beta 4 kullanıyorum ve kesinlikle çalışmıyor. Belki Beta 5'te değiştirdiler? NSStringvardır floatValueuzantısı ama Stringyok. Hata alın:'String' does not have member named floatValue
Firo

Nedeni bu olabilir. Ayrıca, dosyanızın en üstünde ithalat Vakfı var mı?
sketchyTech

Bunun çok güvenli olduğunu düşünmüyorum, en azından Swift standartları için, çünkü dizi bir sayı değilse, NSString.floatValue sadece 0 döndürür. Bu, bir İstisnayı tetiklemeli veya en azından nil döndürmelidir.
Ixx

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

23

Çünkü dünyanın bazı yerlerinde örneğin ondalık yerine virgül kullanılıyor. Bir dizeyi float türüne dönüştürmek için bir NSNumberFormatter oluşturmak en iyisidir.

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

18

String'i Float'a şu şekilde dönüştürüyorum:

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

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

Bunun en iyi çözüm olduğunu düşünüyorum (en azından hızlı 4+ için), ana nedeni isteğe bağlı (tersine NSString.floatValue, bir 0şey yanlışsa basitçe geri dönen) döndürmesidir . Bunun NSNumberFormatterdeğiştirildiğini unutmayın NumberFormatter.
Rom

9

Güncelleme

Kabul edilen cevap, daha güncel bir yol gösterir

Hızlı 1

Paul Hegarty, 2015 yılında Stanford'un CS193p sınıfında şu şekilde göstermiştir:

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

Her seferinde bunu yapmak zorunda kalmamak için hesaplanmış bir mülk bile oluşturabilirsiniz.

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

5

Kabul edilen çözümü kullanarak, "1.1" değerimin (.floatValue dönüşümünü kullanırken) 1.10000002384186'ya dönüştürüleceğini buluyordum, ki bu istediğim şey değildi. Ancak, onun yerine .doubleValue kullanırsam, istediğim 1.1'i elde ederdim.

Örneğin, kabul edilen çözümü kullanmak yerine şunu kullandım:

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

Benim durumumda çift kesinliğe ihtiyacım yoktu, ancak .floatValue'yu kullanmak bana doğru sonucu vermiyordu.

Sadece başka birinin aynı sorunla karşılaşması ihtimaline karşı bunu tartışmaya eklemek istedim.


5

Aşağıda size isteğe bağlı bir Float verilecektir, stick a! sonunda bir Float olduğunu biliyorsanız veya if / let'i kullanın.

let wageConversion = Float(wage.text)

4

İşte Paul Hegarty'nin rdprado'nun cevabındaki çözümünün Swift 3 uyarlaması, buna bazı opsiyonel kontroller eklendi (sürecin herhangi bir kısmı başarısız olursa 0.0 döndürür):

var wageFloat:Float = 0.0

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

Bu arada, Stanford'un CS193p dersini hala Objective-C dersi verirken iTunes University'yi kullanarak aldım.

Paul Hegarty'yi FANTASTIC eğitmeni olarak buldum ve Swift'de iOS geliştiricisi olarak başlayan herkese bu sınıfı şiddetle tavsiye ediyorum !!!


1
Swift 3 veya sonrası için tek doğru cevap budur. NumberFormatterKullanıcı tarafından girilen kayan nokta sayılarıyla ilgilenmek için a kullanmanız gerekir .
rmaddy

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

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

3
Bu kodun neden çalıştığını açıklayın. Bu, çalışmasını anlamadan kopyalayıp yapıştırmayı önler.
rayryeng

3

Swift 4'te

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

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


1

Oldukça benzer iki seçeneğiniz var (yaklaşıma ve sonuca göre):

// 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 () Beta 5'te kaldırıldı
carmen_munich

1

Double() aşağıdaki gibi bir Int'den bir Double oluşturur:

var convertedDouble = Double(someInt)

Bunun yalnızca metniniz gerçekten bir sayı içeriyorsa işe yarayacağını unutmayın. Yana Wagebir metin alanıdır, kullanıcı ne isterse girebilir ve Opsiyonel döndü Unbox gittiğimde bu çalışma zamanı hatası tetikleyecektir toInt(). Kutuyu açmaya zorlamadan önce dönüşümün başarılı olup olmadığını kontrol etmelisiniz.

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

Düzenle:

Metnin bir tam sayı olacağından eminseniz, bunun gibi bir şey yapabilirsiniz ( textUITextField'da da İsteğe Bağlı olduğunu unutmayın ):

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

Eh, ben sadece tuş takımı bir Ondalık Ped olduğu için kullanıcının sayı girmesine izin veriyorum, bu yüzden gerçekte sayılardan başka bir şey giremezler.
Stephen Fox

1
wageConversionFloatasla float olmayacak, eğer girdi dizesi bir tür float gibi ise doğrudan çöküyor 234.56. nasıl kabul edilmiş / olumlu oylanmış bir çözüm olabilir ...?
holex

Metin ondalık bir değer içeriyorsa bu yanıt çalışmaz. Örnek - 3metin alanı varsa bu cevap geri dönecektir 3.5. Bunun nedeni, metnin önce an'a Int, ardından da Inta'ya dönüştürülmesidir Float.
rmaddy

1
@StephenFox Bir kullanıcının metin alanına sayısal olmayan bir metin yapıştırabileceğini veya kullanıcının harici bir klavyesi olabileceğini unutmayın. Veri girişini sağlamak için asla sadece klavyeye güvenmeyin.
rmaddy

aslında tam sayılarla çalışır, ondalık sayılarla değil. ondalık basamak ölümcül bir hataya neden olur!
Miles Works

1

Bir UITextField giriş değerini almanın ve onu bir float'a atmanın başka bir yolunu buldum:

    var tempString:String?
    var myFloat:Float?

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

1

kullanabilirsiniz,

let wg = Float(wage.text!)

Şamandırayı 2 ondalık basamağa yuvarlamak istiyorsanız:

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

0

Ben böyle yaklaştım. Xcode 6 beta 5'ten kaldırıldığı için "köprüyü geçmek" istemedim, hızlı ve kirli:

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
Çünkü dünyanın bazı yerlerinde örneğin ondalık yerine virgül kullanılıyor. Bir dizeyi float türüne dönüştürmek için bir NSNumberFormatter oluşturmak en iyisidir. @DmitriFuerle'a bakın Cevap
carmen_munich

@ParticallyFrozenOJ toDouble()"10" dizesi ile işlevi denediniz mi, yani ondalık yoksa. Yine de çökecek. Çünkü bu durumda sayı 1 olacak ve bununla ilgilenmiyorsunuz. Çarpacak else if comps[0] == "" || comps[1] == "". Her neyse, din değiştirme konusunda çok ciddisin.
TheTiger

@ParticallyFrozenOJ Ama eğer durum 2014'te de aynıydı. Neyse sorun değil!
TheTiger

0

Tamlık adına, bu, UITextFieldfarklı bir yerel ayarı da dikkate alabilen bir uzantı kullanan bir çözümdür .

Swift 3+ için

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

Genel bir çözüm olarak bu, muhtemelen a döndürmeli Float?ve geçersiz değerleri olarak değerlendirmemelidir 0.0. Arayanın let val = field.floatValue ?? 0.0, belirli bir vakanın kötü sonucu sıfır olarak ele alması gerektiği gibi bir şey yapmasına izin verin .
rmaddy

0

Swift 4/5, sadece Float (değer) kullanın.

let string_value : String = "123200"

let float_value : Float = Float(string_value)

print(float_value)

Cevap: 123200


-1

Bunu kullan:

 // 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 () Beta 5'te kaldırıldı
carmen_munich

-4

Kolay yol:

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

Aynı yaklaşımı diğer hesaplamalar için de kullanabilirsiniz, umarım bu yardım !!


3
Bu kadar harika, soruyordufloat
Jack
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.