Number of occurrences of substring in string in Swift

后端 未结 11 919
夕颜
夕颜 2020-12-02 19:37

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.

T

相关标签:
11条回答
  • 2020-12-02 20:17

    Solution which uses a higher order functions

    func subStringCount(str: String, substr: String) -> Int {
        { $0.isEmpty ? 0 : $0.count - 1 } ( str.components(separatedBy: substr))
    }
    

    Unit Tests

    import XCTest
    
        class HigherOrderFunctions: XCTestCase {
    
            func testSubstringWhichIsPresentInString() {
                XCTAssertEqual(subStringCount(str: "hello Swift Swift and Swift", substr: "Swift"), 3)
            }
    
            func testSubstringWhichIsNotPresentInString() {
                XCTAssertEqual(subStringCount(str: "hello", substr: "Swift"), 0)
            }
    
        }
    
    0 讨论(0)
  • 2020-12-02 20:24

    I'd recommend an extension to string in Swift 3 such as:

    extension String {
        func countInstances(of stringToFind: String) -> Int {
            var stringToSearch = self
            var count = 0
            while let foundRange = stringToSearch.range(of: stringToFind, options: .diacriticInsensitive) {
                stringToSearch = stringToSearch.replacingCharacters(in: foundRange, with: "")
                count += 1
            }
            return count
        }
    }
    

    It's a loop that finds and removes each instance of the stringToFind, incrementing the count on each go-round. Once the searchString no longer contains any stringToFind, the loop breaks and the count returns.

    Note that I'm using .diacriticInsensitive so it ignore accents (for example résume and resume would both be found). You might want to add or change the options depending on the types of strings you want to find.

    0 讨论(0)
  • 2020-12-02 20:27

    My solution, maybe it will be better to use String.Index instead of Int range but I think in such way it is a bit easier to read.

    extension String {
        func count(of char: Character, range: (Int, Int)? = nil) -> Int {
            let range = range ?? (0, self.count)
    
            return self.enumerated().reduce(0) {
                guard ($1.0 >= range.0) && ($1.0 < range.1) else { return $0 }
                return ($1.1 == char) ? $0 + 1 : $0
            }
        }
    }
    
    0 讨论(0)
  • 2020-12-02 20:33

    For the sake of completeness – and because there is a regex tag – this is a solution with Regular Expression

    let string = "hello Swift Swift and Swift"
    let regex = try! NSRegularExpression(pattern: "swift", options: .caseInsensitive)
    let numberOfOccurrences = regex.numberOfMatches(in: string, range: NSRange(string.startIndex..., in: string))
    

    The option .caseInsensitive is optional.

    0 讨论(0)
  • 2020-12-02 20:34

    I needed a way to count substrings that may contain the start of the next matched substring. Leveraging dwsolbergs extension and Strings range(of:options:range:locale:) method I came up with this String extension

    extension String
    {
        /**
         Counts the occurrences of a given substring by calling Strings `range(of:options:range:locale:)` method multiple times.
    
         - Parameter substring : The string to search for, optional for convenience
    
         - Parameter allowOverlap : Bool flag indicating whether the matched substrings may overlap. Count of "                                                                    
    0 讨论(0)
  • 2020-12-02 20:36

    Try this

    var mainString = "hello Swift Swift and Swift"
    var count = 0
    
    mainString.enumerateSubstrings(in: mainString.startIndex..<mainString.endIndex, options: .byWords) { (subString, subStringRange, enclosingRange, stop) in
    
        if case let s? = subString{
    
            if s.caseInsensitiveCompare("swift") == .orderedSame{
                count += 1
            }
        }
    
    
    }
    
    print(count)
    
    0 讨论(0)
提交回复
热议问题