Swift - Comment convertir une chaîne en double

242

J'essaie d'écrire un programme IMC en langage rapide. Et j'ai ce problème: comment convertir une chaîne en double?

Dans Objective-C, je peux faire comme ceci:

double myDouble = [myString doubleValue];

Mais comment puis-je y parvenir en langage Swift?

Oh oui
la source
1
Cela a changé dans Swift 2, voir la nouvelle réponse en utilisant le nouvel initialiseur disponible Double (): stackoverflow.com/a/32850058/276626
Paul Solt

Réponses:

205

Swift 4.2+ String to Double

Vous devez utiliser les nouveaux initialiseurs de type pour convertir entre les types String et numériques (Double, Float, Int). Il renverra un type facultatif (Double?) Qui aura la valeur correcte ou nil si la chaîne n'était pas un nombre.

Remarque: La propriété NSString doubleValue n'est pas recommandée car elle renvoie 0 si la valeur ne peut pas être convertie (c'est-à-dire: mauvaise entrée utilisateur).

let lessPrecisePI = Float("3.14")

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

Déballez les valeurs pour les utiliser en utilisant 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!)")
}

Vous pouvez convertir des nombres et des devises formatés à l'aide de la NumberFormatterclasse.

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

Formats monétaires

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

En savoir plus sur mon article de blog sur la conversion des types String en Double (et en devise) .

Paul Solt
la source
2
un autre problème est qu'il ne prend pas en charge les nombres dans des paramètres régionaux différents de 1 000,00, si vous utilisez d'autres formats comme 1 000,00, cela couperait les 2 décimales à la fin. C'est du moins ce qui se passe pour Objective-C. - Selon la documentation Apple: (Ils ne sont pas sensibles aux paramètres régionaux) Les méthodes de commodité suivantes ignorent toutes les caractères d'espace initial (whitespaceSet) et ignorent les caractères de fin. Ils ne sont pas sensibles aux paramètres régionaux. NSScanner ou NSNumberFormatter peuvent être utilisés pour une analyse des nombres plus puissante et adaptée aux paramètres régionaux.
mskw
@mskw J'ai ajouté des détails supplémentaires sur l'utilisation de NumberFormatter pour analyser la devise. Dans mon code, je vais enchaîner plusieurs tentatives de formatage pour convertir en utilisant la syntaxe if / let afin de pouvoir analyser à la fois les nombres formatés en devise (1 000,00 $) ou les nombres formatés (1 000). Vous ne savez pas toujours comment l'utilisateur entrera des nombres, donc être capable de prendre en charge les deux est idéal avec un groupe d'instructions if / let.
Paul Solt
276

Mise à jour Swift 2 Il existe de nouveaux initialiseurs disponibles qui vous permettent de le faire de manière plus idiomatique et sûre (comme de nombreuses réponses l'ont noté, la valeur double de NSString n'est pas très sûre car elle renvoie 0 pour les valeurs non numériques. Cela signifie que les valeurs doubleValuede "foo"et "0"sont le même.)

let myDouble = Double(myString)

Cela retourne une option, donc dans des cas comme en passant "foo"doubleValueaurait retourné 0, l'intialiseur disponible sera de retour nil. Vous pouvez utiliser un guard, if-letou mappour gérer laOptional<Double>

Message d'origine: vous n'avez pas besoin d'utiliser le constructeur NSString comme le propose la réponse acceptée. Vous pouvez simplement le combler comme ceci:

(swiftString as NSString).doubleValue
Jarsen
la source
5
ohai, Jarsen. Un inconvénient de cette approche est qu'elle n'échouera pas si la chaîne n'est pas un double valide. Au lieu de cela, vous obtiendrez simplement 0,0. Autrement dit, le résultat de - [NSString doubleValue]est Doubleen rapide comme apposé sur Double?( Optional<Double>). Ceci est différent de la fonction Swift String toInt()qui retourne Int?et indique dans les documents qu'elle "... accepte les chaînes qui correspondent à l'expression régulière" [- +]? [0-9] + "uniquement."
Derrick Hathaway
Oui, utiliser .toInt()serait mieux. Cependant, c'était plus une réponse à la façon de faire exactement la même chose, mais dans Swift.
Jarsen
Cette approche vous couple étroitement à Foundation, et ne fonctionnera probablement pas sur les implémentations de Swift autres qu'Apple.
Erik Kerber
5
Dans Swift 2.0, Double.init?(_ text: String)un initialiseur disponible est désormais disponible.
mixel
3
Ce n'est pas la meilleure approche. Il échouera en fonction du séparateur décimal. Ce sera bien avec '.' mais pas avec ','. NSNumberFormatter prendra en charge le séparateur décimal utilisé dans la localisation actuelle.
Julian Król
75

Pour un peu plus de sensation Swift, l'utilisation NSFormatter()évite le transtypage en NSStringet retourne nillorsque la chaîne ne contient pas de Doublevaleur (par exemple, "test" ne reviendra pas 0.0).

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

Alternativement, étendre le Stringtype de Swift :

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

et l'utiliser comme toInt():

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

Cela renvoie une option Double?qui doit être déballée.

Soit avec déballage forcé:

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

ou avec une instruction if let:

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

Mise à jour: pour la localisation, il est très facile d'appliquer des paramètres régionaux à NSFormatter comme suit:

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

Enfin, vous pouvez utiliser NSNumberFormatterCurrencyStylesur le formateur si vous travaillez avec des devises où la chaîne contient le symbole monétaire.

RyuX51
la source
J'aime l'idée d'étendre la classe String pour les applications qui utiliseront la conversion à plusieurs endroits. Mais je ne vois pas l'avantage de la complexité d'invoquer NSNumberFormatter, car la conversion en NSString et l'utilisation de .doubleValue semblent être au moins aussi directes, et plus faciles à lire et à mémoriser.
clearlight
12
En fait, l'avantage d'utiliser NSNumberFormatter () est que la méthode numberFromString: retournera nil si la chaîne contient des caractères qui ne constituent pas un double. Le problème avec doubleValue sur NSString est qu'il retournera toujours un double (0,0 pour "test" par exemple). Donc, si vous avez affaire à toutes sortes de chaînes et que vous souhaitez tester si la chaîne est juste un double, pas de caractères supplémentaires, l'utilisation de NSNumberFormatter est la solution.
dirkgroten
4
Cela échoue sur le français.
Peter K.
1
C'est une excellente solution, mais en utilisant uniquement ce code, cela ne fonctionnera pas dans les pays où les virgules sont utilisées comme séparateurs (y compris la France comme @PeterK. Mentionné). J'ai essayé d'écrire un commentaire avec la solution, mais c'était trop long donc j'ai dû en faire une réponse à la place. C'est parti: Solution modifiée
Jacob R
53

Une autre option ici consiste à convertir ceci en un NSStringet à l'utiliser:

let string = NSString(string: mySwiftString)
string.doubleValue
Keith Smiley
la source
13
Je souhaite qu'il y ait une meilleure façon de procéder. Comment savoir si l'analyse a échoué, par exemple.
Ryan Hoffman
2
@RyanHoffman Malheureusement, le contrat NSString doubleValue n'a jamais fourni quoi que ce soit. Tout ce que vous obtenez est 0,0 si la chaîne ne commence pas par une représentation valide d'un nombre, HUGE_VAL et -HUGE_VAL en cas de dépassement / dépassement. Si vous voulez savoir pourquoi l'analyse a échoué, je pense que vous devez vous pencher sur NSNumberFormatter, qui a été conçu pour gérer la conversion nombre / chaîne de manière plus robuste.
Jarsen
Puisqu'il peut être difficile de trouver cette réponse, la voici:(swiftString as NSString).doubleValue
LearnCocos2D
24

Voici une méthode d'extension qui vous permet d'appeler simplement doubleValue () sur une chaîne Swift et d'obtenir un double retour (l'exemple de sortie vient en premier)

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

Voici la méthode d'extension:

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

Aucune vérification d'erreur, mais vous pouvez l'ajouter si vous en avez besoin.

Millie Smith
la source
20

Depuis Swift 1.1, vous pouvez directement passer Stringau const char *paramètre.

import Foundation

let str = "123.4567"
let num = atof(str) // -> 123.4567

atof("123.4567fubar") // -> 123.4567

Si vous n'aimez pas obsolète atof:

strtod("765.4321", nil) // -> 765.4321

Une mise en garde: le comportement de conversion est différent de NSString.doubleValue.

atofet strtodaccepter la 0xchaîne hexadécimale préfixée:

atof("0xffp-2") // -> 63.75
atof("12.3456e+2") // -> 1,234.56
atof("nan") // -> (not a number)
atof("inf") // -> (+infinity)

Si vous préférez le .doubleValuecomportement, nous pouvons toujours utiliser le CFStringpontage:

let str = "0xff"
atof(str)                      // -> 255.0
strtod(str, nil)               // -> 255.0
CFStringGetDoubleValue(str)    // -> 0.0
(str as NSString).doubleValue  // -> 0.0
rintaro
la source
Je suis fan de cette approche au lieu de me lancer NSString.
Sam Soffes
10

Dans Swift 2.0, le meilleur moyen est d'éviter de penser comme un développeur Objective-C. Vous ne devez donc pas «convertir une chaîne en double» mais vous devez «initialiser un double à partir d'une chaîne». Doc Apple ici: https://developer.apple.com/library/ios//documentation/Swift/Reference/Swift_Double_Structure/index.html#//apple_ref/swift/structctr/Double/s:FSdcFMSdFSSGSqSd_

Il s'agit d'un init facultatif, vous pouvez donc utiliser l'opérateur de coalescence nul (??) pour définir une valeur par défaut. Exemple:

let myDouble = Double("1.1") ?? 0.0
Toom
la source
Double.init?(_ text: String)devenir disponible dans Swift 2.0. Vous devez le mentionner. Les autres réponses ne sont pas ici parce que les gens pensent comme les développeurs Objective-C mais parce que cet initialiseur n'était pas disponible plus tôt.
mixel
En effet, vous avez raison. Ceci n'est disponible que dans Swift 2.0, je le mentionnerai :) Mais comme dans d'autres langues, vous initialisez un type avec un autre et ne vous attendez pas à ce qu'un type puisse être converti en un autre. Long débat mais en tant que développeur Obj-C, j'ai de nombreuses mauvaises pratiques lors du codage avec Swift et c'est l'une d'entre elles :)
Toom
10

Sur SWIFT 3 , vous pouvez utiliser:

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

Remarque: - Si une chaîne contient des caractères autres que des chiffres ou un groupe approprié aux paramètres régionaux ou des séparateurs décimaux, l'analyse échouera. - Tous les caractères de séparateur d'espace avant ou arrière dans une chaîne sont ignorés. Par exemple, les chaînes «5», «5» et «5» produisent toutes le nombre 5.

Tiré de la documentation: https://developer.apple.com/reference/foundation/numberformatter/1408845-number

Jorge Luis Jiménez
la source
10

Je n'ai pas vu la réponse que je cherchais. Je viens de poster ici le mien au cas où cela pourrait aider quelqu'un. Cette réponse n'est valable que si vous n'avez pas besoin d'un format spécifique .

Swift 3

extension String {
    var toDouble: Double {
        return Double(self) ?? 0.0
    }
}
TomCobo
la source
9

Essaye ça:

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

REMARQUE

Supprimé dans la version bêta 5. Cela ne fonctionne plus?

CW0007007
la source
1
bridgeToObjectiveC () a été supprimé dans Xcode 6 Beta 5. La méthode de Mr Smiley est la plus rapide que j'ai trouvée en ce moment
faraquet99
7

Ceci s'appuie sur la réponse de @Ryu

Sa solution est excellente tant que vous êtes dans un pays où les points sont utilisés comme séparateurs. Par défaut, NSNumberFormatterutilise les paramètres régionaux des périphériques. Par conséquent, cela échouera dans tous les pays où une virgule est utilisée comme séparateur par défaut (y compris la France comme @PeterK. Mentionné) si le nombre utilise des points comme séparateurs (ce qui est normalement le cas). Pour définir les paramètres régionaux de ce NSNumberFormatter sur US et donc utiliser des points comme séparateurs, remplacez la ligne

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

avec

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

Par conséquent, le code complet devient

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

Pour l'utiliser, appelez simplement "Your text goes here".toDouble()

Cela retournera une option Double?

Comme @Ryu l'a mentionné, vous pouvez soit forcer le déballage:

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

ou utilisez une if letdéclaration:

if let myDouble = myDouble {
    println("The value is \(myDouble)") // prints: The value is 4.2
}
Jacob R
la source
1
Ceci est la bonne réponse. La version Swift 3 sera NumberFormatter().number(from: myString)?.doubleValue
Nicolas Leo
7

SWIFT 4

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

Swift 4.0

essaye ça

 let str:String = "111.11"
 let tempString = (str as NSString).doubleValue
 print("String:-",tempString)
Vishal Vaghasiya
la source
6

Swift: 4 et 5

Il existe peut-être deux façons de procéder:

  1. Chaîne -> Int -> Double:

    let strNumber = "314"
    if let intFromString = Int(strNumber){
        let dobleFromInt = Double(intFromString)
        print(dobleFromInt)
    }
  2. Chaîne -> NSString -> Double

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

Utilisez-le comme bon vous semble en fonction de vos besoins en code.

Abhirajsinh Thakore
la source
La première méthode ne fonctionne pas pour moi, mais la seconde fonctionne plutôt bien.
Saurabh
@Saurabh, pouvez-vous nous en dire plus sur ce qu'était votre chaîne.?
Abhirajsinh Thakore
5

Veuillez le vérifier sur le terrain de jeu!

let sString = "236.86"

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

Au fait dans mon Xcode

.toDouble () - n'existe pas

.doubleValue crée une valeur 0.0 à partir de chaînes non numériques ...

Mamazur
la source
4

1.

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

2.

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

Peut-être cette aide pour vous.

Daxesh Nagar
la source
4

Comme déjà souligné, la meilleure façon d'y parvenir est de lancer directement:

(myString as NSString).doubleValue

À partir de cela, vous pouvez créer une extension Swift String native élégante:

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

Cela vous permet d'utiliser directement:

myString.doubleValue

Qui effectuera le casting pour vous. Si Apple ajoute un doubleValueà la chaîne native, il vous suffit de supprimer l'extension et le reste de votre code se compilera automatiquement très bien!

Firo
la source
La méthode d'Apple serait appelée .toDouble ... comme toInt. C'est une étrange omission. Probablement corrigé dans une future version de Swift. J'aime la méthode d'extension la meilleure, garde le code propre.
n13
La valeur de retour doit être un double PAS un flotteur
Leo Dabus
4

SWIFT 3

Pour effacer, il existe aujourd'hui une méthode par défaut:

public init?(_ text: String)de Doubleclasse.

Il peut être utilisé pour toutes les classes.

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

Vyacheslav
la source
2

Extension avec paramètres régionaux facultatifs

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
        }
    }
}
imike
la source
1
J'ai ajouté l'exemple de Swift 3.1. Que voulez-vous dire par "... et ajoutez un exemple pour les paramètres régionaux"? 🙂
imike
1

Ou vous pourriez faire:

var myDouble = Double((mySwiftString.text as NSString).doubleValue)
jr00n
la source
1

Vous pouvez utiliser StringEx . Il s'étend Stringavec des conversions de chaîne en nombre, y compris toDouble().

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

Il vérifie la chaîne et échoue si elle ne peut pas être convertie en double.

Exemple:

import StringEx

let str = "123.45678"
if let num = str.toDouble() {
    println("Number: \(num)")
} else {
    println("Invalid string")
}
Stas
la source
1

Swift 4

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

Ce qui fonctionne aussi:

// 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.
Bijan
la source
REMARQUE: 'scanDouble' a été déconseillé dans iOS 13.0
uplearnedu.com
0

Utilisez ce code dans Swift 2.0

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

Maninderjit Singh
la source
0

L'utilisation Scannerdans certains cas est un moyen très pratique d'extraire des nombres d'une chaîne. Et il est presque aussi puissant que NumberFormatterlorsqu'il s'agit de décoder et de gérer différents formats de nombres et paramètres régionaux. Il peut extraire des nombres et des devises avec différents séparateurs décimaux et de groupe.

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

    }
}

Cependant, il existe des problèmes avec les séparateurs qui pourraient être conçus comme des délimiteurs de mots.

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

Il n'y a aucun problème pour détecter automatiquement les paramètres régionaux. Notez que groupingSeparator dans les paramètres régionaux français dans la chaîne "Mon salaire est 9 999,99 €" n'est pas un espace, bien qu'il puisse s'afficher exactement comme un espace (ici ce n'est pas le cas). C'est pourquoi le code ci-dessous fonctionne !$0.isWhitespacecorrectement sans filtrer les caractères.

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)
Paul B
la source
-1

Je trouve plus lisible pour ajouter une extension à String comme suit:

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

et alors vous pourriez juste écrire votre code:

myDouble = myString.doubleValue
Gutty1
la source
-1

mon problème était une virgule donc je le résous de cette façon:

extension String {
    var doubleValue: Double {
        return Double((self.replacingOccurrences(of: ",", with: ".") as NSString).doubleValue)
    }
}
Murat Akdeniz
la source
-3
var stringValue = "55"

var convertToDouble = Double((stringValue as NSString).doubleValue)
Mo Abdulmalik
la source
-6

nous pouvons utiliser la valeur CDouble qui sera obtenue par myString.doubleValue

ANIL.MUNDURU
la source
Erreur: 'String' n'a pas de membre nommé 'doubleValue'
Matthew Knippen
@Matthew Oui, il n'y a pas de membre appelé "double valeur", nous pouvons donc utiliser CDouble Value
ANIL.MUNDURU
1
en.wikipedia.org/wiki/… Référez-vous à des nombres complexes et lisez la documentation de référence Swift. Il n'y a pas de CDouble ... Parlez-vous de Swift ou d'une autre langue? Et je veux dire rapide sans extensions?
Adrian Sluyters du