替换 Swift 中的 enumerateSubstringsInRange 3

Replacement for enumerateSubstringsInRange in Swift 3

我正在将代码从 Swift 2 升级到 Swift 3 和 运行 以解决此错误:

wordcount.swift:7:5: error: value of type 'String' has no member 'enumerateSubstringsInRange' line.enumerateSubstringsInRange(range, options: .ByWords) {w,,,_ in

在 Swift 2 中,此方法来自编译器识别的 String 扩展。

我无法在 Swift 3 库中找到此方法。它出现在 Foundation 的文档中:

https://developer.apple.com/library/ios/documentation/Cocoa/Reference/Foundation/Classes/NSString_Class/index.html#//apple_ref/occ/instm/NSString/enumerateSubstringsInRange:options:usingBlock:

我的整个脚本是:

import Foundation

var counts = [String: Int]()

while let line = readLine()?.lowercased() {
    let range = line.characters.indices
    line.enumerateSubstringsInRange(range, options: .ByWords) {w,_,_,_ in
        guard let word = w else {return}
        counts[word] = (counts[word] ?? 0) + 1
    }
}

for (word, count) in (counts.sorted {[=11=].0 < .0}) {
    print("\(word) \(count)")
}

它适用于 Swift 2.2(模数我已经 为 Swift 3 所做的更改,例如 lowercase -> lowercasedsort -> sorted) 但无法使用 Swift 3.

进行编译

而且非常 st运行gely,Swift 3 命令行编译器和 XCode 8 Beta 中的 Swift 迁移助手都不建议替换,因为它确实如此对于许多其他重命名的方法。也许 enumerateSubstringsInRange 已被弃用或其参数名称已更改?

如果您在 Playground 中键入 str.enumerateSubstrings,您将看到以下作为完成选项:

enumerateSubstrings(in: Range<Index>, options: EnumerationOptions, body: (substring: String?, substringRange: Range<Index>, enclosingRange: Range<Index>, inout Bool) -> ())

除了解决新的 enumerateSubstrings(in:options:body:) 语法之外,您还需要更改获取字符串 range 的方式:

import Foundation

var counts = [String: Int]()

while let line = readLine()?.lowercased() {
    let range = line.startIndex ..< line.endIndex
    line.enumerateSubstrings(in: range, options: .byWords) {w,_,_,_ in
        guard let word = w else {return}
        counts[word] = (counts[word] ?? 0) + 1
    }
}

for (word, count) in (counts.sorted {[=11=].0 < .0}) {
    print("\(word) \(count)")
}