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

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

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

double myDouble = [myString doubleValue];

Но как я могу достичь этого на языке Свифт?

Swift 2+ String to Double

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

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

Используйте метод Swift 2+

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

Подробнее о моем сообщении в блоге о преобразовании строк в двойные типы .

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

 let myDouble = Double(myString) 

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

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

 (swiftString as NSString).doubleValue 

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

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

Альтернативно, расширяя String тип Swift:

 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 } 

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

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

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

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

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

Вот метод расширения, который позволяет вам просто вызвать 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 } } 

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

Начиная с 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 

В Swift 2.0 лучший способ – не думать, как разработчик Objective-C. Таким образом, вы не должны «преобразовывать строку в двойную», но вам следует «инициализировать Double from the String». Документ Apple здесь: 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 

Попробуй это:

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

ЗАМЕТКА

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

В 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

Это основано на ответе @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 } 

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

Swift 3

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

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

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

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

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

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

SWIFT 3

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

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

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

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

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 

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

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

 (myString as NSString).doubleValue 

Исходя из этого, вы можете сделать гладкое родное расширение Swift String:

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

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

 myString.doubleValue 

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

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

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

попробуй это

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

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

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

Вы можете использовать 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") } 

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

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

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

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

Swift: – 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) 

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

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

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

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

 myDouble = myString.doubleValue 

моя проблема была запятой, поэтому я решаю ее так:

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

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

  • Оператор равенства Swift для вложенных массивов
  • Как отобразить индикатор активности с текстом на iOS 8 с помощью Swift?
  • Параметр Inout в асинхронном обратном вызове не работает должным образом
  • Синглтон в Свифт
  • Проверить пустую строку в Swift?
  • почему я получаю «Должен переводить авторезистирующую маску в ограничения, чтобы иметь _setHostsLayoutEngine: YES» в xcode 6 beta
  • Переопределение свойства суперclassа с разным типом в Swift
  • Как создать экземпляры подclassов управляемого объекта в расширении NSManagedObject Swift?
  • Является ли этот ответ от компилятора действительным?
  • Интроспекция и дженерики Swift
  • Есть ли способ для Interface Builder визуализировать представления IBDesignable, которые не переопределяют drawRect:
  • Interesting Posts

    Ошибка? # 1146 – Таблица “xxx.xxxxx” не существует

    Как я могу форматировать число в строку с ведущими нулями?

    Можем ли мы предположить значения массива по умолчанию в Java? например, предположим, что массив int задан для всех нhive?

    В каком режиме современные 64-разрядные чип-чипы Intel запускают загрузочный сектор?

    Призматическое подстановочное взаимодействие

    Преобразование дат UTC в другие часовые пояса

    «Недостижимая прямая база», вызванная множественным наследованием

    eclipse, обновлять файлы, отредактированные внешним редактором

    Как удалить всю папку и содержимое?

    Есть ли библиотека планировщика заданий для node.js?

    zip-подобная функция, которая прокладывает до самой длинной длины?

    Запустите Scrapy spider в Задаче Сельдерея

    Не удалось найти пространство имен SpringNamespaceHandler для пространства имен XML

    databind свойство Source для WebBrowser в WPF

    Как реализовать наследование Active Record в Ruby on Rails?

    Давайте будем гением компьютера.