Home > Software design >  How to check the string doesn’t contain any letters in swift?
How to check the string doesn’t contain any letters in swift?

Time:08-24

i have trouble during making the letter checker, my code is like this: if !containLetters(“1234h”){print(“pass”)}

my function is

    func containsOnlyNum(input: String) -> Bool {
         var ok = false
         for chr in input {
             for check in "1234567890.-"{
                if chr == check{
                    ok = true
                }
             }
             if ok != true{
                 return false
             }
         }
         return true
    }

If I check for “h” then didn’t pass, but if i check for ”1h” then it still pass! Please help me to fix this problem. I will give a big thank for anyone who helped me

CodePudding user response:

You can check that a string contains only the characters you're interested in like this:

extension String {
    var containsOnlyNum: Bool {
        let wanted = CharacterSet.decimalDigits
            .union(CharacterSet(charactersIn: "-."))
        return unicodeScalars
            .allSatisfy(wanted.contains)
    }
}

"-12.34".containsOnlyNum  // true

"A1234".containsOnlyNum   // false

But if you are interested in numbers, then this is a problem:

"-12.-34.".containsOnlyNum  // true

Instead, you can just try casting the string to a double and see if it is a number or not

Double("1234") != nil // true, a number
Double("-1.234") != nil // true, a number


Double("A1234") != nil  // false, not a number
Double("-12.-34.") != nil  // false, not a number

Which is almost right unless you don't want this case:

Double("1234e2") != nil // true, a number

But you can use both checks if you don't want to allow that, or else if you are able to parse a Double from the input you can just do the cast.

CodePudding user response:

The simplest way to fix the algorithm is this way:

func containsOnlyNum(input: String) -> Bool {
     // check every character
     for chr in input {
         var isNum = false
         
         for check in "1234567890.-"{
            if chr == check {
                isNum = true
                // if we have found a valid one, we can break the iteration
                break
            }
         }
         
         if !isNum {
             return false
         }
     }
    
     return true
}


print(containsOnlyNum(input: "1234")) // true
print(containsOnlyNum(input: "1234h")) // false

However, then you can directly simplify it to:

func containsOnlyNum(input: String) -> Bool {
    return input.allSatisfy { chr in
        "1234567890.-".contains(chr)
    }
}

which does exatly the same but uses allSatisfy and contains functions, which represent the logical operators ALL and EXISTS.

However, programmers normally use regular expressions for similar tasks:

func containsOnlyNum(input: String) -> Bool {
    return input.range(of: "^[0-9.\\-] $", options: .regularExpression) != nil
}
  • Related