Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Number of occurrences of substring in string in Swift

Tags:

regex

swift

My main string is "hello Swift Swift and Swift" and substring is Swift. I need to get the number of times the substring "Swift" occurs in the mentioned string.

This code can determine whether the pattern exists.

var string = "hello Swift Swift and Swift"

if string.rangeOfString("Swift") != nil {
    println("exists")
}

Now I need to know the number of occurrence.

like image 757
Reza Avatar asked Jul 31 '15 12:07

Reza


People also ask

How do you find the number of occurrences of a substring in a string?

The count() method returns the number of occurrences of a substring in the given string.

How do you find number of occurrences of a character in a string in Swift?

We can count the number of occurrences of a substring in the string using the components(separatedBy:) instance method in Swift.

How do you check if a string contains a substring in Swift?

You can use range(of:options:) , which finds and returns the range of the first occurrence of a given string within the string if found, and return a nil if not. If the range is not equals nil , that's mean we find a substring within the string.

What is a Swift substring?

Substrings. When you get a substring from a string—for example, using a subscript or a method like prefix(_:) —the result is an instance of Substring , not another string. Substrings in Swift have most of the same methods as strings, which means you can work with substrings the same way you work with strings.


3 Answers

A simple approach would be to split on "Swift", and subtract 1 from the number of parts:

let s = "hello Swift Swift and Swift"
let tok =  s.components(separatedBy:"Swift")
print(tok.count-1)

This code prints 3.

Edit: Before Swift 3 syntax the code looked like this:

let tok =  s.componentsSeparatedByString("Swift")
like image 96
Sergey Kalinichenko Avatar answered Oct 08 '22 19:10

Sergey Kalinichenko


Should you want to count characters rather than substrings:

extension String {
    func count(of needle: Character) -> Int {
        return reduce(0) {
            $1 == needle ? $0 + 1 : $0
        }
    }
}
like image 33
mxcl Avatar answered Oct 08 '22 18:10

mxcl


Optimising dwsolbergs solution to count faster. Also faster than componentsSeparatedByString.

extension String {
    /// stringToFind must be at least 1 character.
    func countInstances(of stringToFind: String) -> Int {
        assert(!stringToFind.isEmpty)
        var count = 0
        var searchRange: Range<String.Index>?
        while let foundRange = range(of: stringToFind, options: [], range: searchRange) {
            count += 1
            searchRange = Range(uncheckedBounds: (lower: foundRange.upperBound, upper: endIndex))
        }
        return count
    }
}

Usage:

// return 2
"aaaa".countInstances(of: "aa")
  • If you want to ignore accents, you may replace options: [] with options: .diacriticInsensitive like dwsolbergs did.
  • If you want to ignore case, you may replace options: [] with options: .caseInsensitive like ConfusionTowers suggested.
  • If you want to ignore both accents and case, you may replace options: [] with options: [.caseInsensitive, .diacriticInsensitive] like ConfusionTowers suggested.
  • If, on the other hand, you want the fastest comparison possible and you can guarantee some canonical form for composed character sequences, then you may consider option .literal and it will only perform exact matchs.
like image 19
Cœur Avatar answered Oct 08 '22 20:10

Cœur