在 Swift 中将文本限制为一定数量的单词
Posted
技术标签:
【中文标题】在 Swift 中将文本限制为一定数量的单词【英文标题】:Limit text to a certain number of words in Swift 【发布时间】:2021-09-30 12:54:42 【问题描述】:在移动应用程序中,我使用的 API 只能处理大约 300 个单词。如何在 Swift 中修剪字符串以使其不包含更多单词?
原生 .trimmingCharacters(in: CharacterSet)
似乎无法做到这一点,因为它旨在修剪某些字符。
【问题讨论】:
单词或字符?对于字符,你可以使用prefix(_:)
developer.apple.com/documentation/swift/string/2894830-prefix,对于单词,你可能要数(单词的数量,用什么分隔?空格)?然后,调用prefix(_:)
,重新组合你的字符串。
【参考方案1】:
没有现成的方法来限制字符串中的单词数。
如果您查看this post,它使用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]
【讨论】:
您使用的是句子 startIndex 而不是字符串索引。请注意,一旦达到所需的单词数,就无需继续枚举单词。您可以简单地将您忽略的停止(第 4 个)参数设置为 true。您还应该扩展 StringProtocol 以支持子字符串extension StringProtocol
987654331 var endIndex = self.endIndex
987654333 enumerateSubstrings(in: startIndex..., options: .byWords) _, range, _, stop in
987654335 if words == n
987654337 endIndex = range.upperBound
987654339
987654341
987654343 @
Leo,感谢您的反馈。我认为有一种方法可以终止评估,但这是一个快速的答案,我没有深入挖掘。我也无法弄清楚如何返回 StringProtocol 而不是 String。扩展 StringProtocol 是有意义的。您要提交自己的答案吗?
很好地了解使用 sentence.startIndex。 (已修复)。)我开始编写一次性代码,并没有足够仔细地审查编辑以将其转换为扩展。
哦,没关系。我尝试使用您的版本,但有一个错字。以上是关于在 Swift 中将文本限制为一定数量的单词的主要内容,如果未能解决你的问题,请参考以下文章