iaa
iaa

Reputation: 49

Count how many times a special character (non-spacing mark) occurs in a string in Swift

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

Answers (2)

Martin R
Martin R

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

Andreas Oetjen
Andreas Oetjen

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

Related Questions