user3675188
user3675188

Reputation: 7419

How to check is a string or number?

I have an array ["abc", "94761178","790"]

I want to iterate each and check is a String or an Int?

How to check it?

How to convert "123" to integer 123?

Upvotes: 74

Views: 107694

Answers (18)

Sai kumar Reddy
Sai kumar Reddy

Reputation: 1829

    extension String {
        var isNumber: Bool {
            return !isEmpty && rangeOfCharacter(from: CharacterSet.decimalDigits.inverted) == nil
        }
    }
        
        let numericString = "12345"
        let nonNumericString = "abc123"
        
        print(numericString.isNumber)    // true
        print(nonNumericString.isNumber) // false
        
extension String {
 var isSignedNumber: Bool {
            let allowedCharacters = CharacterSet(charactersIn: "+-").union(CharacterSet.decimalDigits)
            return !isEmpty && rangeOfCharacter(from: allowedCharacters.inverted) == nil
        }
}
    
        let positiveNumber = "+123"
        let negativeNumber = "-456"
        let nonNumericString = "abc123"
        
        print(positiveNumber.isSignedNumber) // true
        print(negativeNumber.isSignedNumber) // true
        print(nonNumericString.isSignedNumber) // false

Upvotes: 0

Alchi
Alchi

Reputation: 849

This code will return an array of converted integers:


["abc", "94761178","790"].map(Int.init) // returns [ nil, 94761178, 790 ]

OR

["abc", "94761178","790"].map { Int($0) ?? 0 } // returns [ 0, 94761178, 790 ]

Upvotes: 0

Amir Khorsandi
Amir Khorsandi

Reputation: 3718

I think using NumberFormatter is an easy way: (Swift 5)

import Foundation

extension String {

    private static let numberFormatter = NumberFormatter()

    var isNumeric : Bool {
        Self.numberFormatter.number(from: self) != nil
    }
}

Upvotes: 6

Harry Zhang
Harry Zhang

Reputation: 827

Simple solution like this:

extension String {
    public var isNumber: Bool {
        return !isEmpty && rangeOfCharacter(from: CharacterSet.decimalDigits.inverted) == nil
    }
}

Upvotes: 9

Nilanshu Jaiswal
Nilanshu Jaiswal

Reputation: 1703

You can use this for integers of any length.

func getIntegerStrings(from givenStrings: [String]) -> [String]
{
    var integerStrings = [String]()
    for string in givenStrings
    {
        let isValidInteger = isInteger(givenString: string)
        if isValidInteger { integerStrings.append(string) }
    }
    return integerStrings
}

func isInteger(givenString: String) -> Bool
{
    var answer = true
    givenString.forEach { answer = ("0"..."9").contains($0) && answer }
    return answer
}

func getIntegers(from integerStrings: [String]) -> [Int]
{
    let integers = integerStrings.compactMap { Int($0) }
    return integers
}

let strings = ["abc", "94761178", "790", "18446744073709551615000000"]
let integerStrings = getIntegerStrings(from: strings)
let integers = getIntegers(from: integerStrings)

print(integerStrings) // ["94761178", "790", "18446744073709551615000000"]
print(integers) // [94761178, 790]

However, as pointed out by @Can, you can get the integer value for the number only up to 2^31 - 1 (signed integer limit on 32-bit arch). For the larger value, however, you will still get the string representation.

Upvotes: 0

Bence Pattogato
Bence Pattogato

Reputation: 3900

I think the nicest solution is:

extension String {
    var isNumeric : Bool {
        return Double(self) != nil
    }
}

Upvotes: 31

CryingHippo
CryingHippo

Reputation: 5086

Here is a small Swift version using String extension :

Swift 3/Swift 4 :

extension String  {
    var isNumber: Bool {
        return !isEmpty && rangeOfCharacter(from: CharacterSet.decimalDigits.inverted) == nil
    }
}

Swift 2 :

   extension String  {
        var isNumber : Bool {
            get{
                return !self.isEmpty && self.rangeOfCharacterFromSet(NSCharacterSet.decimalDigitCharacterSet().invertedSet) == nil
            }
        }
   }

Upvotes: 76

Thiru P
Thiru P

Reputation: 11

This code works for me for Swift 3/4

  func isNumber(textField: UITextField) -> Bool {
    let allowedCharacters = CharacterSet.decimalDigits
    let characterSet = CharacterSet(charactersIn: textField.text!)
    return allowedCharacters.isSuperset(of: characterSet)
  //        return true 
  }

Upvotes: 0

Boris
Boris

Reputation: 322

This way works also with strings with mixed numbers:

public extension String {
func isNumber() -> Bool {
    return !self.isEmpty && self.rangeOfCharacter(from: CharacterSet.decimalDigits) != nil && self.rangeOfCharacter(from: CharacterSet.letters) == nil
}}

So u get something like this: enter image description here

Upvotes: 4

Said Sikira
Said Sikira

Reputation: 4543

Swift 3, 4

extension String {
    var isNumber: Bool {
        let characters = CharacterSet.decimalDigits.inverted
        return !self.isEmpty && rangeOfCharacter(from: characters) == nil
    }
}

Upvotes: 9

Mohamed.A.A
Mohamed.A.A

Reputation: 364

Swift 3.0 version

func isNumber(stringToTest : String) -> Bool {
    let numberCharacters = CharacterSet.decimalDigits.inverted
    return !s.isEmpty && s.rangeOfCharacter(from:numberCharacters) == nil
}

Upvotes: 1

AMTourky
AMTourky

Reputation: 1200

Starting from Swift 2, String.toInt() was removed. A new Int Initializer was being introduced: Int(str: String)

for target in ["abc", "94761178","790"]
{
  if let number = Int(target)
  {
     print("value: \(target) is a valid number. add one to get :\(number+1)!")
  }
  else
  {
    print("value: \(target) is not a valid  number.")
  }
}

Upvotes: 21

Anil Gupta
Anil Gupta

Reputation: 1225

Xcode 8 and Swift 3.0

We can also check :

 //MARK: - NUMERIC DIGITS
        class func isString10Digits(ten_digits: String) -> Bool{

            if !ten_digits.isEmpty {

                let numberCharacters = NSCharacterSet.decimalDigits.inverted
                return !ten_digits.isEmpty && ten_digits.rangeOfCharacter(from: numberCharacters) == nil 
            }
            return false
        }

Upvotes: 0

Kyle Clegg
Kyle Clegg

Reputation: 39480

Be aware that checking a string/number using the Int initializer has limits. Specifically, a max value of 2^32-1 or 4294967295. This can lead to problems, as a phone number of 8005551234 will fail the Int(8005551234) check despite being a valid number.

A much safer approach is to use NSCharacterSet to check for any characters matching the decimal set in the range of the string.

let number = "8005551234"
let numberCharacters = NSCharacterSet.decimalDigitCharacterSet().invertedSet
if !number.isEmpty && number.rangeOfCharacterFromSet(numberCharacters) == nil {
    // string is a valid number
} else {
    // string contained non-digit characters
}

Additionally, it could be useful to add this to a String extension.

public extension String {

    func isNumber() -> Bool {
        let numberCharacters = NSCharacterSet.decimalDigitCharacterSet().invertedSet
        return !self.isEmpty && self.rangeOfCharacterFromSet(numberCharacters) == nil
    }

}

Upvotes: 47

If you want to accept a more fine-grained approach (i.e. accept a number like 4.5 or 3e10), you proceed like this:

func isNumber(val: String) -> Bool
{
   var result: Bool = false
   let parseDotComNumberCharacterSet = NSMutableCharacterSet.decimalDigitCharacterSet()
   parseDotComNumberCharacterSet.formUnionWithCharacterSet(NSCharacterSet(charactersInString: ".e"))

            let noNumberCharacters = parseDotComNumberCharacterSet.invertedSet
            if let v = val
            {
                result = !v.isEmpty && v.rangeOfCharacterFromSet(noNumberCharacters) == nil
            }
   return result
}

For even better resolution, you might draw on regular expression..

Upvotes: 0

Ian Fell
Ian Fell

Reputation: 7

Get the following isInteger() function from the below stackoverflow post posted by corsiKa: Determine if a String is an Integer in Java

And I think this is what you want to do (where nameOfArray is the array you want to pass)

void convertStrArrayToIntArray( int[] integerArray ) {

    for (int i = 0; i < nameOfArray.length(); i++) {
        if (!isInteger(nameOfArray[i])) {
            integerArray[i] = nameOfArray[i].toString();
        }
    }

}

Upvotes: -6

codester
codester

Reputation: 37189

Edit Swift 2.2:

In swift 2.2 use Int(yourArray[1])

var yourArray = ["abc", "94761178","790"]
var num = Int(yourArray[1])
if num != nil {
 println("Valid Integer")
}
else {
 println("Not Valid Integer")
}

It will show you that string is valid integer and num contains valid Int.You can do your calculation with num.

From docs:

If the string represents an integer that fits into an Int, returns the corresponding integer.This accepts strings that match the regular expression "[-+]?[0-9]+" only.

Upvotes: 61

Antonio
Antonio

Reputation: 72810

The correct way is to use the toInt() method of String, and an optional binding to determine whether the conversion succeeded or not. So your loop would look like:

let myArray = ["abc", "94761178","790"]

for val in myArray {
    if let intValue = val.toInt() {
        // It's an int
        println(intValue)
    } else {
        // It's not an int
        println(val)
    }
}

The toInt() method returns an Int?, so an optional Int, which is nil if the string cannot be converted ton an integer, or an Int value (wrapped in the optional) if the conversion succeeds.

The method documentation (shown using CMD+click on toInt in Xcode) says:

If the string represents an integer that fits into an Int, returns the corresponding integer. This accepts strings that match the regular expression "[-+]?[0-9]+" only.

Upvotes: 4

Related Questions