Swift – Come convertire String in Double

Sto provando a scrivere un programma BMI in un linguaggio veloce. E ho avuto questo problema: come convertire una stringa in una doppia?

In Objective-C, posso fare così:

double myDouble = [myString doubleValue];

Ma come posso ottenere questo in Swift?

Swift 2+ da String a Double

È necessario utilizzare i nuovi inizializzatori del tipo per convertire tra tipi String e numerici (Double, Float, Int). Restituirà un tipo facoltativo (Double?) Che avrà il valore corretto o zero se la stringa non era un numero.

Nota: la proprietà doubleValue di NSString non è consigliata perché restituisce 0 se il valore non può essere convertito (ad es. Input utente errato).

Usa il metodo Swift 2+

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

Scollega i valori per usarli usando 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!)") } 

Maggiori informazioni sul mio post sul blog sulla conversione da String a Double types .

Aggiornamento Swift 2 Ci sono nuovi inizializzatori disponibili che ti permettono di farlo in un modo più idiomatico e sicuro (come hanno notato molte risposte, il doppio valore di NSString non è molto sicuro perché restituisce 0 per valori non numerici. Ciò significa che il valore doubleValue di "foo" e "0" sono uguali.)

 let myDouble = Double(myString) 

Ciò restituisce un opzionale, quindi in casi come passare "foo" dove doubleValue avrebbe restituito 0, l’intializer fessibile restituirà nil . Puoi usare una guard , if-let o map per gestire il Optional

Post originale: non è necessario utilizzare il costruttore NSString come propone la risposta accettata. Puoi semplicemente collegarlo in questo modo:

 (swiftString as NSString).doubleValue 

Per un po ‘più di sentimento Swift, l’uso di NSFormatter() evita il casting su NSString e restituisce nil quando la stringa non contiene un valore Double (ad es. “Test” non restituirà 0.0 ).

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

In alternativa, estendere il tipo di String di Swift:

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

e usarlo come toInt() :

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

Questo restituisce un Double? opzionale Double? che deve essere scartato.

O con lo srotolamento forzato:

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

o con una dichiarazione if se:

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

Aggiornamento: per la localizzazione, è molto semplice applicare locales al NSFormatter come segue:

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

Infine, puoi usare NSNumberFormatterCurrencyStyle sul formattatore se stai lavorando con valute dove la stringa contiene il simbolo di valuta.

Un’altra opzione qui è la conversione in NSString e l’utilizzo di:

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

Ecco un metodo di estensione che ti permette di chiamare semplicemente doubleValue () su una stringa Swift e ottenere un doppio back (l’output di esempio viene prima)

 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 

Ecco il metodo di estensione:

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

Nessun controllo degli errori, ma puoi aggiungerlo se ne hai bisogno.

A partire da Swift 1.1, è ansible passare direttamente il parametro String a const char * .

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

Se non ti piace deprecated atof :

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

Un avvertimento: il comportamento della conversione è diverso da NSString.doubleValue .

atof e strtod accettano 0x stringa prefissata esadecimale:

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

Se si preferisce il comportamento .doubleValue , possiamo ancora utilizzare il bridging CFString :

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

In Swift 2.0 il modo migliore è quello di evitare di pensare come uno sviluppatore Objective-C. Quindi non dovresti “convertire una stringa in una doppia” ma dovresti “inizializzare un doppio da una stringa”. Apple doc qui: https://developer.apple.com/library/ios//documentation/Swift/Reference/Swift_Double_Structure/index.html#//apple_ref/swift/structctr/Double/s:FSdcFMSdFSSGSqSd_

È un init opzionale in modo da poter utilizzare l’operatore coalescente nil (??) per impostare un valore predefinito. Esempio:

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

Prova questo:

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

NOTA

Rimosso in Beta 5. Questo non funziona più?

Su SWIFT 3 , puoi usare:

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

Nota: – Se una stringa contiene caratteri diversi da cifre numeriche o separatori di gruppi o decimali appropriati per le impostazioni internazionali, l’analisi fallirà. – Tutti i caratteri di separazione dello spazio iniziale o finale in una stringa vengono ignorati. Ad esempio, le stringhe “5”, “5” e “5” producono tutte il numero 5.

Tratto dalla documentazione: https://developer.apple.com/reference/foundation/numberformatter/1408845-number

Questo sta prendendo le mosse dalla risposta di @Ryu

La sua soluzione è ottima se ti trovi in ​​un paese in cui i punti vengono utilizzati come separatori. Per impostazione predefinita NSNumberFormatter utilizza le impostazioni NSNumberFormatter dei dispositivi. Quindi questo fallirà in tutti i paesi in cui una virgola viene utilizzata come separatore predefinito (inclusa la Francia come @PeterK. Menzionata) se il numero utilizza punti come separatori (che di solito è il caso). Per impostare le impostazioni internazionali di questo NSNumberFormatter come Stati Uniti e quindi utilizzare i punti come separatori, sostituire la linea

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

con

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

Pertanto il codice completo diventa

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

Per usare questo, basta chiamare "Your text goes here".toDouble()

Questo restituirà un Double? opzionale Double?

Come @Ryu ha menzionato puoi forzare lo srotolamento:

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

o usa un’istruzione if let :

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

Non ho visto la risposta che stavo cercando. Inserisco qui il mio nel caso in cui possa aiutare qualcuno. Questa risposta è valida solo se non hai bisogno di un formato specifico.

Swift 3

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

Si prega di controllare sul parco giochi!

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

A proposito, nel mio Xcode

.toDouble () – non esiste

.doubleValue crea valore 0.0 da stringhe non numeriche …

SWIFT 3

Per cancellare, al giorno d’oggi c’è un metodo predefinito:

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

Può essere usato per tutte le classi.

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

SWIFT 4

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

1.

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

2.

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

Potrebbe essere questo aiuto per te.

Come già sottolineato, il modo migliore per ottenere questo è con il casting diretto:

 (myString as NSString).doubleValue 

Basandoti su questo, puoi creare un’estensione Swift nativa nativa:

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

Questo ti permette di usare direttamente:

 myString.doubleValue 

Che eseguirà il casting per te. Se Apple aggiunge un doubleValue alla stringa nativa, devi solo rimuovere l’estensione e il resto del codice verrà compilato automaticamente!

Estensione con impostazioni internazionali opzionali

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

Swift 4.0

prova questo

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

O potresti fare:

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

Puoi usare StringEx . Estende le String con conversioni da stringa a numero compreso toDouble() .

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

Verifica la stringa e fallisce se non può essere convertito in doppio.

Esempio:

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

Cosa funziona anche:

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

Usa questo codice in Swift 2.0

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

Swift: – 4

Ci sono forse due modi per farlo:

  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) 

Usalo comunque a tuo piacimento in base alle tue esigenze del codice.

Trovo più leggibile aggiungere un’estensione a String come segue:

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

e quindi potresti scrivere il tuo codice:

 myDouble = myString.doubleValue 

il mio problema era la virgola, quindi la risolvo in questo modo:

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

possiamo usare il valore CDouble che sarà ottenuto da myString.doubleValue