Check if string is a valid double value in Swift
21,543
Solution 1
It is indeed more efficient not to create a number formatter every time we do a conversion:
extension String {
struct NumFormatter {
static let instance = NumberFormatter()
}
var doubleValue: Double? {
return NumFormatter.instance.number(from: self)?.doubleValue
}
var integerValue: Int? {
return NumFormatter.instance.number(from: self)?.intValue
}
}
Solution 2
edit/update: Xcode 11 or later • Swift 5.1 or later
You can use Double
initializer init?<S>(_ text: S) where S : StringProtocol
to create an instance property on StringProtocol
and use it to check if a String
or Substring
is a valid Double
:
extension StringProtocol {
var double: Double? { Double(self) }
var float: Float? { Float(self) }
var integer: Int? { Int(self) }
}
Testing
let str = "2.9"
if let value = str.double {
print(value) // "2.9\n"
} else {
print("invalid input")
}
str.prefix(1).integer // 2
str.suffix(1).integer // 9
Solution 3
Why not let it return false
? Or true
of course.
extension String {
func isInt() -> Bool {
if let intValue = Int(self) {
return true
}
return false
}
func isFloat() -> Bool {
if let floatValue = Float(self) {
return true
}
return false
}
func isDouble() -> Bool {
if let doubleValue = Double(self) {
return true
}
return false
}
func numberOfCharacters() -> Int {
return self.characters.count
}
}
Or even better, as suggested by @LeoDabus:
extension String {
var isInteger: Bool { return Int(self) != nil }
var isFloat: Bool { return Float(self) != nil }
var isDouble: Bool { return Double(self) != nil }
}
Author by
Michael Voccola
Updated on January 20, 2020Comments
-
Michael Voccola over 4 years
In Swift, how can one check if a string is a valid double value? I have been using the following extension from this question (but as a float) but if the value cannot be converted, it simply returns "0":
extension String { var doubleValue:Double? { return (self as NSString).doubleValue } }
Ideally, I would like it to return
nil
so it can be caught in anif-let
, like so:if let i = str.doubleValue { object.price = i } else { // Tell user the value is invalid }
-
EmilioPelaez almost 9 yearsI would suggest you cache NSNumberFormatter, if you use this method a lot (for example on a tableViewCell) you would benefit from caching it.
-
Blake Merryman almost 9 yearsIf going this route, any reason to not make the structure a first-class member of the entire class extension? Then you can easily extend string to also support
integerValue
,boolValue
, etc. and share the sameFormatter
. -
Roman Safin about 8 yearsit is a bad pattern to use snake case for swift developer, check out the camel case.
-
Hedylove over 7 yearsNote for others: NSNumberFormatter() has been renamed to NumberFormatter in Swift 3 so the struct name will give you errors. All you have to do is change it's name.
-
Fengson over 6 years@EmilioPelaez How would you go about caching it?
-
Leo Dabus over 6 years@Fengson his question was done when the answer was in Swift 1 and at the time there was no Double(_ string:) initializer. this answer shows how to do it in Swift 3.x and later stackoverflow.com/a/27705739/2303865
-
Michael Voccola about 6 yearsThat is definitely cleaner!
-
Leo Dabus almost 5 yearsWhy would youl return FALSE for all negative numbers?
-
Leo Dabus almost 5 yearsYou can simply return not equal to nil and there is no need to make it a method. If there is no need to pass any value to it. You can make them all computed properties with a getter but no setter
extension StringProtocol { var isInteger: Bool { return Int(self) != nil } var isFloat: Bool { return Float(self) != nil } var isDouble: Bool { return Double(self) != nil } }
-
Leo Dabus over 4 yearsNote that this is no pure Swift. It requires you to import Foundation.