How to find out if letter is Alphanumeric or Digit in Swift
I want to count the number of letters, digits and special characters in the following string:
let phrase = "The final score was 32-31!"
I tried:
for tempChar in phrase {
if (tempChar >= "a" && tempChar <= "z") {
letterCounter++
}
// etc.
but I'm getting errors. I tried all sorts of other variations on this - still getting error - such as:
could not find an overload for '<=' that accepts the supplied arguments
Solution 1:
For Swift 5 see rustylepord's answer.
Update for Swift 3:
let letters = CharacterSet.letters
let digits = CharacterSet.decimalDigits
var letterCount = 0
var digitCount = 0
for uni in phrase.unicodeScalars {
if letters.contains(uni) {
letterCount += 1
} else if digits.contains(uni) {
digitCount += 1
}
}
(Previous answer for older Swift versions)
A possible Swift solution:
var letterCounter = 0
var digitCount = 0
let phrase = "The final score was 32-31!"
for tempChar in phrase.unicodeScalars {
if tempChar.isAlpha() {
letterCounter++
} else if tempChar.isDigit() {
digitCount++
}
}
Update: The above solution works only with characters in the ASCII character set,
i.e. it does not recognize Ä, é or ø as letters. The following alternative
solution uses NSCharacterSet
from the Foundation framework, which can test characters
based on their Unicode character classes:
let letters = NSCharacterSet.letterCharacterSet()
let digits = NSCharacterSet.decimalDigitCharacterSet()
var letterCount = 0
var digitCount = 0
for uni in phrase.unicodeScalars {
if letters.longCharacterIsMember(uni.value) {
letterCount++
} else if digits.longCharacterIsMember(uni.value) {
digitCount++
}
}
Update 2: As of Xcode 6 beta 4, the first solution does not work anymore, because
the isAlpha()
and related (ASCII-only) methods have been removed from Swift.
The second solution still works.
Solution 2:
Use the values of unicodeScalars
let phrase = "The final score was 32-31!"
var letterCounter = 0, digitCounter = 0
for scalar in phrase.unicodeScalars {
let value = scalar.value
if (value >= 65 && value <= 90) || (value >= 97 && value <= 122) {++letterCounter}
if (value >= 48 && value <= 57) {++digitCounter}
}
println(letterCounter)
println(digitCounter)
Solution 3:
For Swift 5 you can do the following for simple strings, but be vigilant about handling characters like "1️⃣" , "④" these would be treated as numbers as well.
let phrase = "The final score was 32-31!"
var numberOfDigits = 0;
var numberOfLetters = 0;
var numberOfSymbols = 0;
phrase.forEach {
if ($0.isNumber) {
numberOfDigits += 1;
}
else if ($0.isLetter) {
numberOfLetters += 1
}
else if ($0.isSymbol || $0.isPunctuation || $0.isCurrencySymbol || $0.isMathSymbol) {
numberOfSymbols += 1;
}
}
print(#"\#(numberOfDigits) || \#(numberOfLetters) || \#(numberOfSymbols)"#);