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 }
} 
Share:
21,543
Michael Voccola
Author by

Michael Voccola

Updated on January 20, 2020

Comments

  • Michael Voccola
    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 an if-let, like so:

    if let i = str.doubleValue {
        object.price = i
    } else {
        // Tell user the value is invalid
    }
    
  • EmilioPelaez
    EmilioPelaez almost 9 years
    I 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
    Blake Merryman almost 9 years
    If 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 same Formatter.
  • Roman Safin
    Roman Safin about 8 years
    it is a bad pattern to use snake case for swift developer, check out the camel case.
  • Hedylove
    Hedylove over 7 years
    Note 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
    Fengson over 6 years
    @EmilioPelaez How would you go about caching it?
  • Leo Dabus
    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
    Michael Voccola about 6 years
    That is definitely cleaner!
  • Leo Dabus
    Leo Dabus almost 5 years
    Why would youl return FALSE for all negative numbers?
  • Leo Dabus
    Leo Dabus almost 5 years
    You 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
    Leo Dabus over 4 years
    Note that this is no pure Swift. It requires you to import Foundation.