Reputation: 49
This function searches how many times a character appears in a string:
let str = "الصَّبَاْحُ جَمِيْلٌ"
let char: Character = "َ"
func SpecificLetterCount(_ str:String, _ char:Character) -> Int {
let letters = Array(str); var count = 0
for letter in letters {
if letter == char {
count += 1
}
}
return count
}
print(SpecificLetterCount(str, char)) //Prints 0 , where in fact it should find it 3 times in that string!
In this case the result is 0 , where in fact it should find it 3 times in that string!, but because it is a non-spacing mark (a special character) it can't find it by itself. The same happens with this character: ( e + ́ ) = é , where I can't find ( ́ ) by itself!
Upvotes: 1
Views: 140
Reputation: 539815
Based on the excellent insight from Why are emoji characters like 👩👩👧👦 treated so strangely in Swift strings?, you can do a literal search:
func specificLetterCount(_ str:String, _ char:Character) -> Int {
var count = 0
var pos = str.startIndex
while let range = str[pos...].range(of: String(char), options: .literal) {
count += 1
pos = range.upperBound
}
return count
}
This gives the expected result:
let str = "الصَّبَاْحُ جَمِيْلٌ"
let char: Character = "َ"
print(specificLetterCount(str, char)) // 3
Upvotes: 1
Reputation: 10199
You'll have to work with unicode scalars instead of characters (which are so-called extended grapheme clusters).
Unsafe example:
func SpecificLetterCount(_ str:String, _ char:Character) -> Int {
var count = 0
for s in str.unicodeScalars {
print(s)
if s == char.unicodeScalars.first! {
count += 1
}
}
return count
}
The code is unsafe because of char.unicodeScalars.first!
which expects the char to consist of only one scalar. I leave it as an exercise to make this function safe.
Upvotes: 1