how to convert hashtag in swift? - swift

I want to extract the hashtag.
func getHashtags() -> [String] {
let words = components(separatedBy: " ")
var hashTags = [String]()
for word in words{
if word.hasPrefix("#"){
let hashtag = word.dropFirst()
hashTags.append(String(hashtag))
}
}
return hashTags
}
This method was not a good solution. "I want to eat #rice #eat." Hashtags are extracted well from sentences like
But if the sentence is like this,
Hashtags do not recognize line breaks, so the entire hashtag is not extracted. How can you solve this error? Tell me about the function that extracts the hashtag.

You can reformat your code for something like this. string here is your original text
func getHashtags() -> [String] {
var words = string.components(separatedBy: "#") // Separate words by #
var hashTags = [String]()
// Check if the first word of sentence is a hashtag. If it is not then remove the first word
// ex "firstWord #firstHashtag". Here "firstWord " should be removed
var shouldRemoveFirstWord = !string.hasPrefix("#")
if shouldRemoveFirstWord {
words.removeFirst()
}
for word in words{
let trimmedWord = word.trim()
// If the word has space then get only the first word
let firstWord = word.components(separatedBy: " ")
let hashtag = firstWord[0]
hashTags.append(String(hashtag))
}
return hashTags
}
And for the trim function, you can add it like this
extension String {
func trim() -> String {
return self.trimmingCharacters(in: .whitespacesAndNewlines)
}
}

Related

Reverse words with exclusion rules

I would like to get a func which will be able to reverse a string without affecting special characters, preferably using regex, ex:
Input: “Weather is cool 24/7” -> Output: “rehtaeW si looc 24/7”
Input: “abcd efgh” -> Output: “dcba hgfe”
Input: “a1bcd efg!h” -> Output: “d1cba hgf!e”
I was able to write only for all characters without exceptions, I'm a beginner, and I don't know how to use regexes
func reverseTheWord(reverse: String) -> String {
let parts = reverse.components(separatedBy: " ")
let reversed = parts.map{String($0.reversed())}
let reversedWord = reversed.joined(separator: " ")
return reversedWord
}
thanks in advance!
Here is a solution where I first check what type each word is, only letters, no letters or a mix of letters and other characters and handle each differently.
The first two are self explanatory and for the mix one I first reverse the word and remove all non letters and then reinsert the non letters at their original position
func reverseTheWords(_ string: String) -> String {
var words = string.components(separatedBy: .whitespaces)
for (index, word) in words.enumerated() {
//Only letters
if word.allSatisfy(\.isLetter) {
words[index] = String(word.reversed())
continue
}
//No letters
if !word.contains(where: \.isLetter) { continue }
//Mix
var reversed = word.reversed().filter(\.isLetter)
for (index, char) in word.enumerated() {
if !char.isLetter {
index < reversed.endIndex ? reversed.insert(char, at: index) : reversed.append(char)
}
}
words[index] = String(reversed)
}
return words.joined(separator: " ")
}

How to check if a string contains a substring within an array of strings in Swift?

I have a string "A very nice beach" and I want to be able to see if it contains any words of the substring within the array of wordGroups.
let string = "A very nice beach"
let wordGroups = [
"beach",
"waterfront",
"with a water view",
"near ocean",
"close to water"
]
First solution is for exactly matching the word or phrase in wordGroups using regex
var isMatch = false
for word in wordGroups {
let regex = "\\b\(word)\\b"
if string.range(of: regex, options: .regularExpression) != nil {
isMatch = true
break
}
}
As suggested in the comments the above loop can be replace with a shorter contains version
let isMatch = wordGroups.contains {
string.range(of: "\\b\($0)\\b", options: .regularExpression) != nil
}
Second solution is for simply text if string contains the any of the strings in the array
let isMatch2 = wordGroups.contains(where: string.contains)
So for "A very nice beach" both returns true but for "Some very nice beaches" only the second one returns true
Wasn't too sure how to interpret "to see if it contains any words of the substring within the array of wordGroups", but this solution checks to see if any words of your input string are contained in any substring of your word groups.
func containsWord(str: String, wordGroups: [String]) -> Bool {
// Get all the words from your input string
let words = str.split(separator: " ")
for group in wordGroups {
// Put all the words in the group into set to improve lookup time
let set = Set(group.split(separator: " "))
for word in words {
if set.contains(word) {
return true
}
}
}
return false
}

How to write a Swift String Characters.reverse function in 2021

//MARK: - Reverse every other word
var sampleSentence = "Hey my name is Chris, what is yours?"
func reverseWordsInSentence(sentence: String) -> String {
let allWords = sentence.components(separatedBy: " ")
var newSentence = ""
for word in allWords {
if newSentence != "" {
newSentence += " "
}
let reverseWord = String(word//.characters.reverse()) //Problem
newSentence += word
}
return newSentence
}
I made a tutorial by "Lets Build That App" on YouTube but his video is from 2016. He wrote it like you can see above but the characters function of the String doesn't exist!
There is a few issues regarding the Swift version of that tutorial. First the character property from string has been removed. Second collection reverse method has been renamed to reversed. Third that logic is flawed because it would reverse the punctuations after the words. You can use string enumerateSubstrings in range, use byWords option, to get the range of the words in the sentence and reverse each word as follow:
func reverseWordsInSentence(sentence: String) -> String {
var sentence = sentence
sentence.enumerateSubstrings(in: sentence.startIndex..., options: .byWords) { _, range, _, _ in
sentence.replaceSubrange(range, with: sentence[range].reversed())
}
return sentence
}
var sampleSentence = "Hey my name is Chris, what is yours?"
reverseWordsInSentence(sentence: sampleSentence) // "yeH ym eman si sirhC, tahw si sruoy?"
try this for reverse:
let reverseWord = String(word.reversed())
newSentence += reverseWord
instead of:
let reverseWord = String(word)//.characters.reverse()) //Problem
newSentence += word
output:

replacing for loop to map method

I am stuck about this goal.
Learn about the map method, and use it in place of the loop that converts the array of characters to an array of strings in updateUI().
I have read Documentation and topics about map, but still all my tries did not work.
//change loop below to map method
for letter in currentGame.formattedWord {
letters.append(String(letter))
}
let wordWithSpacing = letters.joined(separator: " ")
correctWordLabel.text = wordWithSpacing
scoreLabel.text = "Wins: \(totalWins), Losses: \(totalLosses)"
treeImageView.image = UIImage(named: "Tree \(currentGame.incorrectMovesRemaining)")
Thanks for help
The String documentation tells us:
A string is a series of characters, such as "Swift", that forms a collection.
So, you can use map to convert each of these characters to individual strings:
let string = "Hello, world"
let letters = string.map { (character: Character) -> String in
return String(character)
}
Or, more concisely:
let letters = string.map { String($0) }
I did it. the problem was that I left the var letters as an empty array and tried to add characters to this array. Now I realized that this was wrong.
func updateUI() {
let letters = currentGame.formattedWord
let mappedLetters = letters.map { String($0)}
/* for letter in currentGame.formattedWord {
letters.append(String(letter))
} */
Thanks all!

Remove stop words from a string without trimming other words in Swift

I am using the following code to remove Stop words from string but it ends up trimming other words, I just want to remove the specific words from a string without trimming other words.
import Foundation
var sentence = "God have created the creatures at his best"
let wordToRemove = "at"
if let range = sentence.range(of: wordToRemove) {
sentence.removeSubrange(range)
}
print(sentence) // God have creed the creures his best
First write an extenstion of Build-In class String
extension String {
func contains(word : String) -> Range<String.Index>?
{
return self.range(of: "\\b\(word)\\b", options: .regularExpression)
}
}
Then write the below code to remove the specific word from a sentence
var sentence = "God have created the creatures at his best"
let wordToRemove = "at"
if let range = sentence.contains(word: wordToRemove) {
sentence.removeSubrange(range)
print(sentence)
}
//Output : God have created the creatures his best
By my understanding of stop words, they can occur at any point in the sentence, including as the first or last word. So a solution should support removing them anywhere in the sentence.
import Foundation
var sentence = "at God have created the creatures at his best at"
let wordsToRemove = ["at", "his"]
let words = sentence.components(separatedBy: " ")
sentence = words.filter({ wordsToRemove.contains($0) == false }).joined(separator:" ")
// sentence is now "God have created the creatures best"
import Foundation
var sentence = "God have created the creatures at at at at his best"
let words = [" at ", " his "]
var index = 0
while index < words.count {
let word = words[index]
if let range = sentence.range(of: word) {
sentence = sentence.replacingOccurrences(of: word, with: " ", options: [], range: range)
} else {
index += 1
}
}
print(sentence)
God have created the creatures best
func replaceText(){
var sentence = "At God have created the creatures at his best aatckkat at."
var arr = [String]()
sentence.enumerateSubstrings(in: sentence.startIndex..<sentence.endIndex, options: .byWords) { (str, r1, r2, stop) in
//Condition for words to be removed
if str! != "at" && str! != "At"{
arr.append(str!)
}
}
sentence = ""
for word in arr{
sentence += "\(word) "
}
print("new altered sentence -> \(sentence)")
}
You can try this way out.