web-dev-qa-db-fra.com

Swift - Comment convertir une chaîne en double

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

En Objective-C, je peux faire comme ceci:

double myDouble = [myString doubleValue];

Mais comment puis-je y parvenir en Swift language?

226
ohyes

Swift 4.2 + chaîne à doubler

Vous devez utiliser les nouveaux initialiseurs de types pour convertir les types String et numeric (Double, Float, Int). Il renverra un type facultatif (Double?) Qui aura la valeur correcte ou nil si la chaîne n'est 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: entrée utilisateur incorrecte).

let lessPrecisePI = Float("3.14")

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

Décompressez les valeurs à 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 formatés et des devises à l'aide de la classe NumberFormatter.

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

Formats de devise

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 de String en types Double (et devise) .

156
Paul Solt

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

let myDouble = Double(myString)

Cela retourne une valeur optionnelle. Ainsi, dans les cas tels que le passage de "foo"doubleValue aurait retourné 0, l'initialiseur disponible retournera nil. Vous pouvez utiliser un guard, if-let ou map pour gérer le Optional<Double>

Original Post: Vous n'avez pas besoin d'utiliser le constructeur NSString comme le propose la réponse acceptée. Vous pouvez simplement le ponter comme ceci:

(swiftString as NSString).doubleValue
271
Jarsen

Pour un peu plus de sensation Swift, utiliser NSFormatter() évite de transtyper vers NSString et renvoie nil lorsque la chaîne ne contient pas de valeur Double (par exemple "test" ne retournera pas 0.0).

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

Vous pouvez également étendre le type String de Swift:

extension String {
    func toDouble() -> Double? {
        return NSNumberFormatter().numberFromString(self)?.doubleValue
    }
}

et l'utiliser comme toInt():

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

Ceci retourne un Double? facultatif qui doit être décompressé.

Soit avec déballage forcé:

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

ou avec une déclaration if let:

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

pdate: Pour la localisation, il est très facile d'appliquer les 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 NSNumberFormatterCurrencyStyle sur le formateur si vous utilisez des devises dont la chaîne contient le symbole monétaire.

71
RyuX51

Une autre option ici est de convertir ceci en un NSString et de l'utiliser:

let string = NSString(string: mySwiftString)
string.doubleValue
53
Keith Smiley

Voici une méthode d’extension qui vous permet d’appeler simplement doubleValue () sur une chaîne Swift et d’obtenir un double retour (un 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 erreur de vérification, mais vous pouvez l'ajouter si vous en avez besoin.

24
Millie Smith

À partir de Swift 1.1, vous pouvez passer directement le paramètre String à const char *.

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 la conversion est différent de NSString.doubleValue.

atof et strtod acceptent 0x chaîne hexagonale 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 comportement .doubleValue, nous pouvons toujours utiliser CFString pontage:

let str = "0xff"
atof(str)                      // -> 255.0
strtod(str, nil)               // -> 255.0
CFStringGetDoubleValue(str)    // -> 0.0
(str as NSString).doubleValue  // -> 0.0
19
rintaro

Je n'ai pas vu la réponse que je cherchais. Je poste juste ici le mien au cas où cela pourrait aider n'importe qui. Cette réponse est valide niquement si vous n'avez pas besoin d'un format spécifique.

Swift

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

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, des séparateurs décimaux ou des groupes appropriés aux paramètres régionaux, l'analyse échouera. - Tous les caractères séparateurs d'espacement avant ou après caractères d'une chaîne sont ignorés. Par exemple, les chaînes "5", "5" et "5" génèrent toutes le nombre 5.

Extraits de la documentation: https://developer.Apple.com/reference/foundation/numberformatter/1408845-number

10
Jorge Luis Jiménez

Dans Swift 2.0, le meilleur moyen consiste à éviter de penser comme un développeur Objective-C. Donc, vous ne devriez pas "convertir une chaîne en un double" mais "initialiser un double à partir d'une chaîne". Appledocumentation ici: https://developer.Apple.com/library/ios//documentation/Swift/Reference/Swift_Double_Structure/index.html#//Apple_ref/Swift/structctr/ Double/s: FSdcFMSdFSSGSqSd _

C'est une init optionnelle, vous pouvez donc utiliser l'opérateur nul coalescent (??) pour définir une valeur par défaut. Exemple:

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

Essaye ça:

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

NOTE

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

9
CW0007007

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, NSNumberFormatter utilise les paramètres régionaux du périphérique. 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 en tant que @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 utiliser des points comme séparateurs pour remplacer 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, il suffit d'appeler "Your text goes here".toDouble()

Cela retournera un Double? facultatif

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

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

ou utilisez une instruction if let:

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

Swift 4

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

S'il vous plaît 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 la valeur 0.0 à partir de chaînes non numériques ...

5
Mamazur

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.

4
Daxesh Nagar

Swift

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

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

Il peut être utilisé pour toutes les classes.

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

4
Vyacheslav

Swift 4.0

essayez ceci

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

Comme indiqué précédemment, le meilleur moyen d'y parvenir consiste à utiliser la coulée directe:

(myString as NSString).doubleValue

En partant de là, vous pouvez créer une extension native Swift String:

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 effectivement un doubleValue à la chaîne native, il vous suffit de supprimer l'extension et le reste de votre code sera automatiquement compilé correctement!

3
Firo

Extension avec locale optionnelle

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

rapide: - 4

Il y a peut-être deux façons de le faire:

  1. String -> Int -> Double:

    let strNumber = "314"
    let intFromString = Int(strNumber)
    let dobleFromInt = Double(intFromString!)
    print(dobleFromInt)
    
  2. String -> NSString -> Double

    let strNumber = "314"
    let NSstringFromString = NSString(string: strNumber as! NSString)
    let doubleFromNSString = NSstringFromString.doubleValue
    print(doubleFromNSString)
    

Utilisez-le comme bon vous semble selon votre besoin du code.

1

Swift 4

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

Ou tu pourrais faire:

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

Vous pouvez utiliser StringEx . Il étend String avec des conversions chaîne à nombre comprenant toDouble().

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

Il vérifie la chaîne et échoue s'il ne peut pas être converti en double.

Exemple:

import StringEx

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

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.
0
Bijan

Utilisez ce code dans Swift 2.0

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

0
Maninderjit Singh