0

在移动应用程序中,我使用的 API 只能处理大约 300 个单词。如何在 Swift 中修剪字符串以使其不包含更多单词?

本机.trimmingCharacters(in: CharacterSet)似乎无法做到这一点,因为它旨在修剪某些字符。

4

1 回答 1

0

没有现成的方法来限制字符串中的单词数。

如果您查看这篇文章,它会记录使用该方法enumerateSubstrings(in: Range)并设置 .byWords 选项。看起来它返回一个Range值数组。

您可以使用它在 String 上创建一个扩展,该扩展将返回该字符串的前 X 个单词:

extension String {
    func firstXWords(_ wordCount: Int) -> Substring {
        var ranges: [Range<String.Index>] = []
        self.enumerateSubstrings(in: self.startIndex..., options: .byWords) { _, range, _, _ in
            ranges.append(range)
        }
        if ranges.count > wordCount - 1 {
            return self[self.startIndex..<ranges[wordCount - 1].upperBound]
        } else {
            return self[self.startIndex..<self.endIndex]
        }
    }
}

如果我们然后运行代码:

let sentence = "I want to an algorithm that could help find out how many words are there in a string separated by space or comma or some character. And then append each word separated by a character to an array which could be added up later I'm making an average calculator so I want the total count of data and then add up all the words. By words I mean the numbers separated by a character, preferably space Thanks in advance"

print(sentence.firstXWords(10))

输出是:

我想要一个可以帮助找出的算法

使用enumerateSubstrings(in: Range)将比使用空格分割字符串提供更好的结果,因为除了普通文本中的空格(换行符、逗号、冒号、em 空格等)之外,还有更多的分隔符。它也适用于日语等语言和中文通常没有单词之间的空格。

您可以重写该函数以在字符串达到所需的字数时立即终止该字符串的枚举。如果您想要一个非常长的字符串中的一小部分单词,这会使其显着更快(上面的代码应该具有O(n)性能,尽管我没有深入挖掘以确保这一点。我也无法弄清楚如何提前终止enumerateSubstrings()函数,虽然我没有那么努力。)

Leo Dabus 提供了我的函数的改进版本。它扩展了 StringProtocol 而不是 String,这意味着它可以处理子字符串。另外,一旦达到您想要的字数,它就会停止,因此查找很长字符串的前几个单词会更快:

extension StringProtocol {
    func firstXWords(_ n: Int) -> SubSequence {
        var endIndex = self.endIndex
        var words = 0
        enumerateSubstrings(in: startIndex..., options: .byWords) { _, range, _, stop in
            words += 1
            if words == n {
                stop = true
                endIndex = range.upperBound
            }
        }
        return self[..<endIndex] }
}
于 2021-07-23T12:26:02.413 回答