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?
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) .
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"
où 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
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.
Une autre option ici est de convertir ceci en un NSString
et de l'utiliser:
let string = NSString(string: mySwiftString)
string.doubleValue
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.
À 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
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
}
}
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
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
Essaye ça:
var myDouble = myString.bridgeToObjectiveC().doubleValue
println(myDouble)
NOTE
Supprimé en version bêta 5. Cela ne fonctionne plus?
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
}
Swift 4
extension String {
func toDouble() -> Double? {
let numberFormatter = NumberFormatter()
numberFormatter.locale = Locale(identifier: "en_US_POSIX")
return numberFormatter.number(from: self)?.doubleValue
}
}
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 ...
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.
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.
essayez ceci
let str:String = "111.11"
let tempString = (str as NSString).doubleValue
print("String:-",tempString)
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!
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
}
}
}
rapide: - 4
Il y a peut-être deux façons de le faire:
String -> Int -> Double:
let strNumber = "314"
let intFromString = Int(strNumber)
let dobleFromInt = Double(intFromString!)
print(dobleFromInt)
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.
Swift 4
extension String {
func toDouble() -> Double {
let nsString = self as NSString
return nsString.doubleValue
}
}
Ou tu pourrais faire:
var myDouble = Double((mySwiftString.text as NSString).doubleValue)
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")
}
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.
Utilisez ce code dans Swift 2.0
let strWithFloat = "78.65" let floatFromString = Double(strWithFloat)