问题
If we have, for example, situation like this:
var myString = "Today was a good day"
What is the best way to return the first word, which is "Today"? I think mapping should be applied, but not sure how.
Thanks.
回答1:
The simplest way I can think of is
Swift 3
let string = "hello world"
let firstWord = string.components(separatedBy: " ").first
Swift 2.2
let string = "hello world"
let firstWord = string.componentsSeparatedByString(" ").first
and if you think you need to use it a lot in your code, make it as an extension
extension String {
func firstWord() -> String? {
return self.components(separatedBy: " ").first
}
}
Usage
let string = "hello world"
let firstWord = string.firstWord()
回答2:
You can use StringProtocol method enumerateSubstrings(in: Range<String.Index>)
with options .byWords
to enumerate the words in your string and just get the first element:
Swift 5.1 • Xcode 11 or later
Note: For older Swift syntax check this post edit history
import Foundation
extension StringProtocol {
var byLines: [SubSequence] { components(separated: .byLines) }
var byWords: [SubSequence] { components(separated: .byWords) }
func components(separated options: String.EnumerationOptions)-> [SubSequence] {
var components: [SubSequence] = []
enumerateSubstrings(in: startIndex..., options: options) { _, range, _, _ in components.append(self[range]) }
return components
}
var firstWord: SubSequence? {
var word: SubSequence?
enumerateSubstrings(in: startIndex..., options: .byWords) { _, range, _, stop in
word = self[range]
stop = true
}
return word
}
var firstLine: SubSequence? {
var line: SubSequence?
enumerateSubstrings(in: startIndex..., options: .byLines) { _, range, _, stop in
line = self[range]
stop = true
}
return line
}
}
Playground Testing:
let string = "• Today was a good day.\n• Tomorrow will be better.\n"
let firstWord = string.firstWord // "Today"
let firstLine = string.firstLine // "• Today was a good day."
let firstLineLastWord = string.firstLine?.byWords.last // day
let firstLineLast2Words = string.firstLine?.byWords.suffix(2) // ["good", "day"]
回答3:
I would prefer using CharacterSet
, since words can be delimited by white-spaces as well as punctuation marks.
var myString = "Today was a good day"
let nonLetters = CharacterSet.letters.inverted
let first = myString.components(separatedBy: nonLetters).first
回答4:
To avoid processing the whole string just to get the first word, you could do this:
let string = "Hello World"
let word1 = string.prefix{ (c:Character) in CharacterSet.letters.contains(c.unicodeScalars.first!) }
来源:https://stackoverflow.com/questions/39667312/how-to-return-a-first-word-from-a-string-in-swift