Swift - Как преобразовать String в Double

Я пытаюсь написать программу BMI на быстром языке. И у меня возникла эта проблема: как преобразовать строку в двойную?

В Objective-C я могу сделать вот так:

double myDouble = [myString doubleValue];

Но как я могу добиться этого на языке Swift?

Ответ 1

Swift 4. 2+ Строка для удвоения

Вы должны использовать инициализаторы нового типа для преобразования между строковым и числовым типами (Double, Float, Int). Он вернет необязательный тип (Double?), Который будет иметь правильное значение или ноль, если строка не была числом.

Примечание. Свойство NSString doubleValue не рекомендуется, поскольку оно возвращает 0, если значение не может быть преобразовано (например, неверный ввод данных пользователем).

let lessPrecisePI = Float("3.14")

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

Разверните значения, чтобы использовать их, используя 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!)")
}

Вы можете конвертировать отформатированные числа и валюту, используя класс NumberFormatter.

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

Форматы валют

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

Читайте больше в моем блоге о преобразовании типа String в Double (и валюту).

Ответ 2

Обновление Swift 2 Существуют новые отказоустойчивые инициализаторы, которые позволяют вам делать это более идиоматичным и безопасным способом (как было отмечено многими ответами, двойное значение NSString не очень безопасно, потому что оно возвращает 0 для значений без номера. Это означает, что doubleValue of "foo" и "0" совпадают.)

let myDouble = Double(myString)

Возвращает необязательный параметр, поэтому в случаях, когда передача "foo", где doubleValue вернула бы 0, возвращаемый intializer вернет nil. Вы можете использовать guard, if-let или map для обработки Optional<Double>

Оригинальное сообщение: Вам не нужно использовать конструктор NSString, как предлагает принятый ответ. Вы можете просто провести его так:

(swiftString as NSString).doubleValue

Ответ 3

Для немного более быстрого ощущения, используя NSFormatter(), избегает кастинга до NSString и возвращает nil, когда строка не содержит значения Double (например, "test" не вернет 0.0).

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

В качестве альтернативы, расширение типа Swift String:

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

и используйте его как toInt():

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

Это возвращает необязательный Double?, который необходимо развернуть.

Либо с принудительной разворачиванием:

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

или с выражением if let:

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

Update: Для локализации очень легко применять локали к NSFormatter следующим образом:

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

Наконец, вы можете использовать NSNumberFormatterCurrencyStyle в форматировании, если работаете с валютами, где строка содержит символ валюты.

Ответ 4

Другим вариантом здесь является преобразование этого в NSString и использование этого:

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

Ответ 5

Здесь используется метод расширения, который позволяет вам просто вызвать doubleValue() в строке Swift и получить двойную обратную сторону (сначала выводится вывод)

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

Здесь метод расширения:

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

Нет проверки ошибок, но вы можете добавить его, если вам это нужно.

Ответ 6

С Swift 1.1 вы можете напрямую передать параметр String в const char *.

import Foundation

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

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

Если вам не нравится устаревший atof:

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

Одно предостережение: поведение преобразования отличается от NSString.doubleValue.

atof и strtod принять 0x префиксную шестнадцатеричную строку:

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

Если вы предпочитаете поведение .doubleValue, мы все равно можем использовать мост CFString:

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

Ответ 7

В Swift 2.0 лучший способ - не думать о разработчике Objective-C. Таким образом, вы не должны "преобразовывать строку в двойную", но вам следует "инициализировать Double from the String". Apple doc здесь: https://developer.apple.com/library/ios//documentation/Swift/Reference/Swift_Double_Structure/index.html#//apple_ref/swift/structctr/Double/s:FSdcFMSdFSSGSqSd_

Это необязательный init, поэтому вы можете использовать оператор объединения nil (??) для установки значения по умолчанию. Пример:

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

Ответ 8

Попробуйте следующее:

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

Примечание

Удалено в бета-версии 5. Это больше не работает?

Ответ 9

В SWIFT 3 вы можете использовать:

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

Примечание:  - Если строка содержит любые символы, отличные от числовых цифр или соответствующие группе или десятичные разделители, синтаксический анализ завершится с ошибкой.  - Любые символы разделителя пробелов или строк в строке игнорируются. Например, строки "5" , "5" и "5" производят номер 5.

Взято из документации: https://developer.apple.com/reference/foundation/numberformatter/1408845-number

Ответ 10

Я не видел ответа, который искал. Я просто отправляю сюда свои сообщения на случай, если это кому-нибудь поможет. Этот ответ действителен, только если вам не нужен определенный формат.

Свифт 3

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

Ответ 11

Это основано на ответе @Ryu

Его решение велико, пока вы находитесь в стране, где точки используются в качестве разделителей. По умолчанию NSNumberFormatter использует локали устройств. Поэтому это не удастся во всех странах, где запятая используется как разделитель по умолчанию (в том числе Франция как @PeterK), если число использует точки в качестве разделителей (что обычно бывает). Чтобы установить локаль этого NSNumberFormatter равным US и, таким образом, использовать точки в качестве разделителей, замените строку

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

с

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

Поэтому полный код становится

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

Чтобы использовать это, просто позвоните "Your text goes here".toDouble()

Это вернет необязательный Double?

Как упоминалось в @Ryu, вы можете либо принудительно развернуть:

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

или используйте оператор if let:

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

Ответ 12

Пожалуйста, проверьте это на детской площадке!

let sString = "236.86"

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

Кстати, в моем Xcode

.toDouble() - не существует

.doubleValue создает значение 0.0 из не числовых строк...

Ответ 13

SWIFT 4

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

Ответ 14

1.

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

2.

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

Может быть, эта помощь для вас.

Ответ 15

SWIFT 3

Чтобы очистить, в настоящее время существует метод по умолчанию:

public init?(_ text: String) класса Double.

Он может использоваться для всех классов.

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

Ответ 16

Swift 4.0

попробуй это

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

Ответ 17

Как уже указывалось, лучший способ достичь этого - с прямым литьем:

(myString as NSString).doubleValue

Создавая это, вы можете сделать плавное расширение Swift String:

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

Это позволяет вам напрямую использовать:

myString.doubleValue

Который выполнит кастинг для вас. Если Apple добавит doubleValue к родной String, вам просто нужно удалить расширение, а остальная часть вашего кода будет автоматически компилироваться.

Ответ 18

Расширение с дополнительным языковым стандартом

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

Ответ 19

Или вы могли бы сделать:

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

Ответ 20

Вы можете использовать StringEx. Он расширяет String с преобразованием строк в число, включая toDouble().

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

Он проверяет строку и терпит неудачу, если ее нельзя преобразовать в double.

Пример:

import StringEx

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

Ответ 21

Свифт: - 4

Есть два способа сделать это:

  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)
    

Используйте его так, как вам нравится, в соответствии с вашими требованиями.

Ответ 22

Swift 4

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

Ответ 23

Что также работает:

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

Ответ 24

Используйте этот код в Swift 2.0

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

Ответ 25

Я нахожу более читаемым, чтобы добавить расширение к String следующим образом:

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

а затем вы можете написать свой код:

myDouble = myString.doubleValue

Ответ 26

Моя проблема была запятой, поэтому я решаю ее следующим образом:

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

Ответ 27

var stringValue = "55"

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

Ответ 28

мы можем использовать значение CDouble, которое будет получено myString.doubleValue