Ma chaîne principale est "hello Swift Swift and Swift" et la sous-chaîne est Swift . Je dois connaître le nombre de fois que la sous-chaîne "Swift" apparaît dans la chaîne mentionnée.
Ce code peut déterminer si le motif existe.
var string = "hello Swift Swift and Swift"
if string.rangeOfString("Swift") != nil {
println("exists")
}
Maintenant, j'ai besoin de connaître le nombre d'occurrences.
Une approche simple consisterait à scinder le "Swift"
et à soustraire 1 du nombre de parties:
let s = "hello Swift Swift and Swift"
let tok = s.components(separatedBy:"Swift")
print(tok.count-1)
Ce code imprime 3.
Edit: Before Syntaxe de Swift 3 le code ressemblait à ceci:
let tok = s.componentsSeparatedByString("Swift")
Je recommanderais une extension de chaîne dans Swift 3 telle que:
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
}
}
C'est une boucle qui trouve et supprime chaque instance de la chaîne stringToFind, en incrémentant le compte à chaque remise. Une fois que la chaîne searchString ne contient plus de chaîneToFind, la boucle est interrompue et le décompte est renvoyé.
Notez que j'utilise .diacriticInsensitive afin qu'il ignore les accents (par exemple, CV et CV seraient tous deux trouvés). Vous voudrez peut-être ajouter ou modifier les options en fonction du type de chaîne que vous souhaitez rechercher.
Optimisation solution de dwsolbergs pour compter plus rapidement. Aussi plus rapide que 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")
options: []
par options: .diacriticInsensitive
comme l'a fait dwsolbergs.options: []
par options: .caseInsensitive
comme suggéré par ConfusionTowers.options: []
par options: [.caseInsensitive, .diacriticInsensitive]
comme suggéré par ConfusionTowers.Si vous souhaitez compter les caractères plutôt que les sous-chaînes:
extension String {
func count(of needle: Character) -> Int {
return reduce(0) {
$1 == needle ? $0 + 1 : $0
}
}
}
J'avais besoin d'un moyen de compter les sous-chaînes pouvant contenir le début de la prochaine sous-chaîne correspondante. Utilisation de dwsolbergs extension et de la chaîne Strings (of: options: range: locale :) method
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 "????????" in "????????????????" is 2 if allowOverlap is **false**, and 3 if it is **true**
- Parameter options : String compare-options to use while counting
- Parameter range : An optional range to limit the search, default is **nil**, meaning search whole string
- Parameter locale : Locale to use while counting
- Returns : The number of occurrences of the substring in this String
*/
public func count(
occurrencesOf substring: String?,
allowOverlap: Bool = false,
options: String.CompareOptions = [],
range searchRange: Range<String.Index>? = nil,
locale: Locale? = nil) -> Int
{
guard let substring = substring, !substring.isEmpty else { return 0 }
var count = 0
let searchRange = searchRange ?? startIndex..<endIndex
var searchStartIndex = searchRange.lowerBound
let searchEndIndex = searchRange.upperBound
while let rangeFound = range(of: substring, options: options, range: searchStartIndex..<searchEndIndex, locale: locale)
{
count += 1
if allowOverlap
{
searchStartIndex = index(rangeFound.lowerBound, offsetBy: 1)
}
else
{
searchStartIndex = rangeFound.upperBound
}
}
return count
}
}
Essaye ça
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)