SWIFT – Hoe string om te zetten naar Dubbel

Ik probeer een BMI-programma in Swift Language te schrijven.
En ik heb dit probleem: hoe een tekenreeks om te zetten naar een dubbele?

In objectief-c kan ik dit doen:

double myDouble = [myString doubleValue];

Maar hoe kan ik dit bereiken in de snelle taal?


1, Autoriteit 100%

Swift 4.2+ String om te verdubbelen

U moet de nieuwe initializers van het type gebruiken om te converteren tussen string- en numerieke typen (dubbel, float, int). Het zal een optioneel type retourneren (dubbel?), Wat de juiste waarde of nul heeft als de tekenreeks geen nummer was.

Opmerking: De eigenschap NSSstring DoubleValue wordt niet aanbevolen omdat het 0 retourneert als de waarde niet kan worden geconverteerd (d.w.z. slechte gebruikersinvoer).

let lessPrecisePI = Float("3.14")
let morePrecisePI = Double("3.1415926536")
let invalidNumber = Float("alphabet") // nil, not a valid number

Stel de waarden uit om ze te gebruiken met behulp van if / let

if let cost = Double(textField.text!) {
    print("The user entered a value price of \(cost)")
} else {
    print("Not a valid number: \(textField.text!)")
}

U kunt geformatteerde nummers en valuta converteren met behulp van de NumberFormatterKlasse.

let formatter = NumberFormatter()
formatter.locale = Locale.current // USA: Locale(identifier: "en_US")
formatter.numberStyle = .decimal
let number = formatter.number(from: "9,999.99")

valuta-indelingen

let usLocale = Locale(identifier: "en_US")
let frenchLocale = Locale(identifier: "fr_FR")
let germanLocale = Locale(identifier: "de_DE")
let englishUKLocale = Locale(identifier: "en_GB") // United Kingdom
formatter.numberStyle = .currency
formatter.locale = usLocale
let usCurrency = formatter.number(from: "$9,999.99")
formatter.locale = frenchLocale
let frenchCurrency = formatter.number(from: "9999,99€")
// Note: "9 999,99€" fails with grouping separator
// Note: "9999,99 €" fails with a space before the €
formatter.locale = germanLocale
let germanCurrency = formatter.number(from: "9999,99€")
// Note: "9.999,99€" fails with grouping separator
formatter.locale = englishUKLocale
let englishUKCurrency = formatter.number(from: "£9,999.99")

Lees meer op mijn blogbericht over het converteren van String naar Double-types (en valuta).


Antwoord 2, autoriteit 97%

Swift 2-update
Er zijn nieuwe initializers die niet kunnen werken waarmee u dit op een meer idiomatische en veilige manier kunt doen (zoals veel antwoorden hebben opgemerkt, is de dubbele waarde van NSString niet erg veilig omdat deze 0 retourneert voor niet-getalwaarden. Dit betekent dat de doubleValuevan "foo"en "0"zijn hetzelfde.)

let myDouble = Double(myString)

Dit retourneert een optioneel, dus in gevallen zoals het doorgeven van "foo"waar doubleValue0 zou hebben geretourneerd, retourneert de mislukte initializer nil. U kunt een guard, if-letof mapgebruiken om de Optional<Double>

Originele post:
U hoeft de NSSstring-constructor niet te gebruiken zoals het geaccepteerde antwoord voorstelt. Je kunt het gewoon zo overbruggen:

(swiftString as NSString).doubleValue

3, Autoriteit 32%

Voor een beetje meer snel gevoel, met behulp van NSFormatter()vermijdt gieten naar NSStringen retourneert nilwanneer de string geen DoubleWaarde (bijv. “Test” retourneert niet 0.0).

let double = NSNumberFormatter().numberFromString(myString)?.doubleValue

U bent alternatief, uitbreiding van Swift’s StringType:

extension String {
    func toDouble() -> Double? {
        return NumberFormatter().number(from: self)?.doubleValue
    }
}

en gebruik het zoals toInt():

var myString = "4.2"
var myDouble = myString.toDouble()

Hierdoor wordt een optionele Double?die moet worden uitgewikkeld.

Met gedwongen uitpakken:

println("The value is \(myDouble!)") // prints: The value is 4.2

of met een als u een verklaring laat zien:

if let myDouble = myDouble {
    println("The value is \(myDouble)") // prints: The value is 4.2
}

update:
Voor lokalisatie is het heel gemakkelijk om locales aan te brengen in de NSFORATE als volgt:

let formatter = NSNumberFormatter()
formatter.locale = NSLocale(localeIdentifier: "fr_FR")
let double = formatter.numberFromString("100,25")

Ten slotte kunt u NSNumberFormatterCurrencyStyleop de formatter gebruiken als u werkt met valuta’s waarbij de tekenreeks het valutasymbool bevat.


Antwoord 4, autoriteit 23%

Een andere optie hier is om dit te converteren naar een NSStringen dat te gebruiken:

let string = NSString(string: mySwiftString)
string.doubleValue

Antwoord 5, autoriteit 10%

Hier is een uitbreidingsmethode waarmee je eenvoudig doubleValue() op een Swift-tekenreeks kunt aanroepen en een dubbele back kunt krijgen (voorbeelduitvoer komt eerst)

println("543.29".doubleValue())
println("543".doubleValue())
println(".29".doubleValue())
println("0.29".doubleValue())
println("-543.29".doubleValue())
println("-543".doubleValue())
println("-.29".doubleValue())
println("-0.29".doubleValue())
//prints
543.29
543.0
0.29
0.29
-543.29
-543.0
-0.29
-0.29

Dit is de extensiemethode:

extension String {
    func doubleValue() -> Double
    {
        let minusAscii: UInt8 = 45
        let dotAscii: UInt8 = 46
        let zeroAscii: UInt8 = 48
        var res = 0.0
        let ascii = self.utf8
        var whole = [Double]()
        var current = ascii.startIndex
        let negative = current != ascii.endIndex && ascii[current] == minusAscii
        if (negative)
        {
            current = current.successor()
        }
        while current != ascii.endIndex && ascii[current] != dotAscii
        {
            whole.append(Double(ascii[current] - zeroAscii))
            current = current.successor()
        }
        //whole number
        var factor: Double = 1
        for var i = countElements(whole) - 1; i >= 0; i--
        {
            res += Double(whole[i]) * factor
            factor *= 10
        }
        //mantissa
        if current != ascii.endIndex
        {
            factor = 0.1
            current = current.successor()
            while current != ascii.endIndex
            {
                res += Double(ascii[current] - zeroAscii) * factor
                factor *= 0.1
                current = current.successor()
           }
        }
        if (negative)
        {
            res *= -1;
        }
        return res
    }
}

Geen foutcontrole, maar u kunt het toevoegen als u het nodig hebt.


Antwoord 6, autoriteit 5%

Ik heb het antwoord dat ik zocht niet gezien.
Ik post hier de mijne voor het geval het iemand kan helpen. Dit antwoord is alleen geldig als u geen specifiek formaat nodig heeft.

Swift 3

extension String {
    var toDouble: Double {
        return Double(self) ?? 0.0
    }
}

Antwoord 7, autoriteit 4%

In Swift 2.0 is de beste manier om niet te denken als een Objective-C-ontwikkelaar. Je moet dus niet “een String naar een Double converteren” maar “een Double van een String initialiseren”. Apple-document hier:
https://developer.apple.com/library/ios//documentation/Swift/Reference/Swift_Double_Structure/index.html#//apple_ref/swift/structctr/Double/s:FSdcFMSdFSSGSqSd_

Het is een optionele init, dus je kunt de nulcoalescentie-operator (??) gebruiken om een standaardwaarde in te stellen. Voorbeeld:

let myDouble = Double("1.1") ?? 0.0

Antwoord 8, autoriteit 4%

Op SWIFT 3kunt u het volgende gebruiken:

if let myDouble = NumberFormatter().number(from: yourString)?.doubleValue {
   print("My double: \(myDouble)")
}

Opmerking:
– Als een tekenreeks andere tekens bevat dan numerieke cijfers of voor de landinstelling geschikte groep- of decimale scheidingstekens, zal het parseren mislukken.
– Voorloop- of volgspaties in een tekenreeks worden genegeerd. Bijvoorbeeld, de strings “ 5”, “5 ” en “5” produceren allemaal het getal 5.

Uit de documentatie gehaald:
https://developer.apple.com/reference/foundation/numberformatter/1408845-number


Antwoord 9, autoriteit 4%

Probeer dit:

  var myDouble = myString.bridgeToObjectiveC().doubleValue
   println(myDouble)

OPMERKING

Verwijderd in bèta 5. Dit werkt niet meer ?


Antwoord 10, autoriteit 3%

Dit bouwt voort op het antwoord van @Ryu

Zijn oplossing is geweldig zolang je in een land bent waar punten als scheidingstekens worden gebruikt. Standaard gebruikt NSNumberFormatterde landinstelling van het apparaat. Dit zal daarom mislukken in alle landen waar een komma als standaardscheidingsteken wordt gebruikt (inclusief Frankrijk als @PeterK. genoemd) als het nummer punten als scheidingstekens gebruikt (wat normaal het geval is). Om de landinstelling van deze NSNumberFormatter in te stellen op US en dus punten als scheidingstekens te gebruiken, vervangt u de regel

return NSNumberFormatter().numberFromString(self)?.doubleValue

met

let numberFormatter = NSNumberFormatter()
numberFormatter.locale = NSLocale(localeIdentifier: "en_US_POSIX")
return numberFormatter.numberFromString(self)?.doubleValue

Daarom wordt de volledige code

extension String {
    func toDouble() -> Double? {
        let numberFormatter = NSNumberFormatter()
        numberFormatter.locale = NSLocale(localeIdentifier: "en_US_POSIX")
        return numberFormatter.numberFromString(self)?.doubleValue
    }
}

Om dit te gebruiken, roept u gewoon "Your text goes here".toDouble()

aan

Hiermee krijg je een optionele Double?

Zoals @Ryu al zei, kun je het uitpakken forceren:

println("The value is \(myDouble!)") // prints: The value is 4.2

of gebruik een if letstatement:

if let myDouble = myDouble {
    println("The value is \(myDouble)") // prints: The value is 4.2
}

Antwoord 11, autoriteit 3%

SWIFT 4

extension String {
    func toDouble() -> Double? {
        let numberFormatter = NumberFormatter()
        numberFormatter.locale = Locale(identifier: "en_US_POSIX")
        return numberFormatter.number(from: self)?.doubleValue
    }
}

Antwoord 12, autoriteit 2%

Swift 4.0

probeer dit

let str:String = "111.11"
 let tempString = (str as NSString).doubleValue
 print("String:-",tempString)

Antwoord 13, autoriteit 2%

Snel: 4 en 5

Er zijn mogelijk twee manieren om dit te doen:

  1. String -> Int -> Dubbel:

    let strNumber = "314"
    if let intFromString = Int(strNumber){
        let dobleFromInt = Double(intFromString)
        print(dobleFromInt)
    }
    
  2. String – & GT; Nsstring – & GT; Dubbel

    let strNumber1 = "314"
    let NSstringFromString = NSString(string: strNumber1)
    let doubleFromNSString = NSstringFromString.doubleValue
    print(doubleFromNSString)
    

Gebruik het hoe dan ook, zoals jij volgens je nodig hebt van de code.


14, Autoriteit 2%

Controleer het op de speeltuin!

let sString = "236.86"
var dNumber = NSNumberFormatter().numberFromString(sString)
var nDouble = dNumber!
var eNumber = Double(nDouble) * 3.7

Trouwens in mijn Xcode

.todouble () – bestaat niet

.DoubleValue Creëerwaarde 0.0 van niet numerieke snaren …


15, Autoriteit 2%

Zoals al opgemerkt, is de beste manier om dit te bereiken, met directe gieten:

(myString as NSString).doubleValue

Gebouw daarvan kunt u een slick native swift string extensie maken:

extension String {
    var doubleValue: Double {
        return (self as NSString).doubleValue
    }
}

Hiermee kunt u direct gebruikmaken van:

myString.doubleValue

die de gieten voor u zullen uitvoeren. Als Apple een doubleValuetoevoegt aan de native-reeks, moet u alleen de extensie verwijderen en de rest van uw code automatisch maken!


16, Autoriteit 2%

1.

let strswift = "12"
let double = (strswift as NSString).doubleValue

2.

var strswift= "10.6"
var double : Double = NSString(string: strswift).doubleValue 

Misschien is dit iets voor jou.


Antwoord 17, autoriteit 2%

SWIFT 3

Ter verduidelijking, er is tegenwoordig een standaardmethode:

public init?(_ text: String)` of `Double` class.

Het kan voor alle klassen worden gebruikt.

let c = Double("-1.0")
let f = Double("0x1c.6")
let i = Double("inf")

, enz.


Antwoord 18

Uitbreiding met optionele landinstelling

Swift 2.2

extension String {
    func toDouble(locale: NSLocale? = nil) -> Double? {
        let formatter = NSNumberFormatter()
        if let locale = locale {
            formatter.locale = locale
        }
        return formatter.numberFromString(self)?.doubleValue
    }
}

Swift 3.1

extension String {
    func toDouble(_ locale: Locale) -> Double {
        let formatter = NumberFormatter()
        formatter.numberStyle = .decimal
        formatter.locale = locale
        formatter.usesGroupingSeparator = true
        if let result = formatter.number(from: self)?.doubleValue {
            return result
        } else {
            return 0
        }
    }
}

Antwoord 19

Of je zou kunnen doen:

var myDouble = Double((mySwiftString.text as NSString).doubleValue)

Antwoord 20

Je kunt StringExgebruiken. Het breidt Stringuit met conversies van tekenreeksen naar cijfers, waaronder toDouble().

extension String {
    func toDouble() -> Double?
}

Het verifieert de string en mislukt als het niet kan worden geconverteerd naar double.

Voorbeeld:

import StringEx
let str = "123.45678"
if let num = str.toDouble() {
    println("Number: \(num)")
} else {
    println("Invalid string")
}

Antwoord 21

Swift 4

extension String {
    func toDouble() -> Double {
        let nsString = self as NSString
        return nsString.doubleValue
    }
}

Antwoord 22

Wat ook werkt:

// Init default Double variable
var scanned: Double()
let scanner = NSScanner(string: "String to Scan")
scanner.scanDouble(&scanned)
// scanned has now the scanned value if something was found.

Antwoord 23

Het gebruik van Scanneris in sommige gevallen een erg handige manier om getallen uit een tekenreeks te extraheren. En het is bijna net zo krachtig als NumberFormatterals het gaat om het decoderen en omgaan met verschillende getalformaten en landinstellingen. Het kan getallen en valuta extraheren met verschillende scheidingstekens voor decimalen en groepen.

import Foundation
// The code below includes manual fix for whitespaces (for French case)
let strings = ["en_US": "My salary is $9,999.99",
               "fr_FR": "Mon salaire est 9 999,99€",
               "de_DE": "Mein Gehalt ist 9999,99€",
               "en_GB": "My salary is £9,999.99" ]
// Just for referce
let allPossibleDecimalSeparators = Set(Locale.availableIdentifiers.compactMap({ Locale(identifier: $0).decimalSeparator}))
print(allPossibleDecimalSeparators)
for str in strings {
    let locale = Locale(identifier: str.key)
    let valStr = str.value.filter{!($0.isWhitespace || $0 == Character(locale.groupingSeparator ?? ""))}
    print("Value String", valStr)
    let sc = Scanner(string: valStr)
    // we could do this more reliably with `filter` as well
    sc.charactersToBeSkipped = CharacterSet.decimalDigits.inverted
    sc.locale = locale
    print("Locale \(locale.identifier) grouping separator: |\(locale.groupingSeparator ?? "")| . Decimal separator: \(locale.decimalSeparator ?? "")")
    while !(sc.isAtEnd) {
        if let val = sc.scanDouble() {
            print(val)
        }
    }
}

Er zijn echter problemen met scheidingstekens die kunnen worden opgevat als scheidingstekens voor woorden.

// This doesn't work. `Scanner` just ignores grouping separators because scanner tends to seek for multiple values
// It just refuses to ignore spaces or commas for example.
let strings = ["en_US": "$9,999.99", "fr_FR": "9999,99€", "de_DE": "9999,99€", "en_GB": "£9,999.99" ]
for str in strings {
    let locale = Locale(identifier: str.key)
    let sc = Scanner(string: str.value)
    sc.charactersToBeSkipped = CharacterSet.decimalDigits.inverted.union(CharacterSet(charactersIn: locale.groupingSeparator ?? ""))
    sc.locale = locale
    print("Locale \(locale.identifier) grouping separator: \(locale.groupingSeparator ?? "") . Decimal separator: \(locale.decimalSeparator ?? "")")
    while !(sc.isAtEnd) {
        if let val = sc.scanDouble() {
            print(val)
        }
    }
}
//     sc.scanDouble(representation: Scanner.NumberRepresentation) could help if there were .currency case

Het is geen probleem om de landinstelling automatisch te detecteren. Merk op dat groupingSeparator in Franse taal in string “Mon salaire est 9999,99€” geen spatie is, hoewel het exact als spatie kan worden weergegeven (hier niet). Daarom werkt de onderstaande code prima zonder dat !$0.isWhitespacetekens worden weggefilterd.

let stringsArr = ["My salary is $9,999.99",
                  "Mon salaire est 9 999,99€",
                  "Mein Gehalt ist 9.999,99€",
                  "My salary is £9,999.99" ]
let tagger = NSLinguisticTagger(tagSchemes: [.language], options: Int(NSLinguisticTagger.Options.init().rawValue))
for str in stringsArr {
    tagger.string = str
    let locale = Locale(identifier: tagger.dominantLanguage ?? "en")
    let valStr = str.filter{!($0 == Character(locale.groupingSeparator ?? ""))}
    print("Value String", valStr)
    let sc = Scanner(string: valStr)
    // we could do this more reliably with `filter` as well
    sc.charactersToBeSkipped = CharacterSet.decimalDigits.inverted
    sc.locale = locale
    print("Locale \(locale.identifier) grouping separator: |\(locale.groupingSeparator ?? "")| . Decimal separator: \(locale.decimalSeparator ?? "")")
    while !(sc.isAtEnd) {
        if let val = sc.scanDouble() {
            print(val)
        }
    }
}
// Also will fail if groupingSeparator == decimalSeparator (but don't think it's possible)

Antwoord 24

Gebruik deze code in Swift 2.0

let strWithFloat = "78.65"
let floatFromString = Double(strWithFloat)

Antwoord 25

In het geval van strings andere karakters bevatten, zoals: "27.8 °C", "52.523553 kM"of "Total: 349.0".

Dit werkt in Swift 4:

let anyString = "52.523553 kM"
let digitsCharacterSet = CharacterSet.init(charactersIn: "0123456789.")
let doubleResult = Double(anyString.components(separatedBy:digitsCharacterSet.inverted).joined())

Let op!Dit werkt niet voor strings die meerdere .zoals "27.8 °C 3.5 kM"


Antwoord 26

Ik vind het leesbaarder om als volgt een extensie aan String toe te voegen:

extension String {
    var doubleValue: Double {
        return (self as NSString).doubleValue
    }
}

en dan kun je gewoon je code schrijven:

myDouble = myString.doubleValue

Antwoord 27

mijn probleem was een komma, dus ik los het op deze manier op:

extension String {
    var doubleValue: Double {
        return Double((self.replacingOccurrences(of: ",", with: ".") as NSString).doubleValue)
    }
}

Antwoord 28

var stringValue = "55"
var convertToDouble = Double((stringValue as NSString).doubleValue)

Antwoord 29

we kunnen CDouble-waarde gebruiken die wordt verkregen door myString.doubleValue

Other episodes