Swift 3 replace words in String, checking against values in array - arrays

Let's say I have a variable of type String holding a single String. In this string, there are 1 or more words. I also have an array of Strings. I want to check the String against the array, looking for, and replacing words found in the array.
For instance, the word "able" is in the array. The word "able" is also in the String variable. I want the word able replaced with the "+" character.
I've tried like this:
//stopWords = array of Strings / keywords = String variable
for words in stopWords {
keywordsFormatted = keywords.replacingOccurrences(of: words, with: "+", options: .regularExpression, range: nil)
}
and that doesn't change anything. I've also tried in a while loop, and a few other ways that I don't even care to recall right now lol. Any help is appreciated

Given
let stopWords = ["red", "green", "blue"]
let keywords = "The sky is blue not green"
let's create a set
let stopWordsSet = Set(stopWords)
and finally let's solve the problem
let result = keywords
.components(separatedBy: " ")
.map { stopWordsSet.contains($0) ? "+" : $0 }
.joined(separator: " ")
Oh... and lets test it
print(result) // The sky is + not +
Please note this solution is case sensitive. Furthermore it will not work is words in keywords are not delimited by spaces. E.g. "The sky is blue, not green" will not work properly because of the ,.
Addendum from Adrian:
If you want to update the textField, just use didSet, like so:
var keywords = "The sky is blue not green" {
didSet {
// if keywords is not empty, set the myTextField.text to keywords
if !keywords.characters.isEmpty {
myTextField.text = keywords
}
}
}

Related

How to get the index of spaces of a string and relate that index of spaces to a new string in javascript?

In JavaScipt
I need to get the index of spaces of a string and relate that index of spaces to a new string.
Example:
The string: "I am okay"
The result: "Y es Iam"
Example 2:
The string: "how are you"
The result: "Iam goo d"
As you can see the index of the spaces has been preserved and related to the resulting string. I do not need anything case-sensative preserved.
I can not include code from what I've tried, as I have no idea how to go about this.
Thanks for your help!
Here's what I came up with:
var srcStrX="How are you";
var applyToStrX="I am good";
function reSpace(srcStr, applyToStr) {
var resultStr="";
var srcStrCopy=srcStr.split("");
var applyToStrSpaceless=applyToStr.split(" ").join("").split("");
while(srcStrCopy.length && applyToStrSpaceless.length) {
var character=srcStrCopy.shift();
if(character==" ") resultStr+=character;
else resultStr+=applyToStrSpaceless.shift();
};
return resultStr;
}
console.log(reSpace(srcStrX, applyToStrX));
console.log(reSpace("When you wish upon a star", "Doesn't matter who you are"));

Swift: How to get one item from shuffled array

I created an array of words and I shuffled it.
I added a button and I want it to print one of the randomisers words in the array in a label. I know how to do that with integers but with stings it seems to be different. How can I do?
This is my code:
IBOutlet weak var label : UILabel!
IBAction getText(_ sender: Any) {
let words = textView.text.components.shuffled()
print (words)
}
I thought I had to add in my button something like
label.text = words
But
It says it can't convert [String] to string
It prints all of the words
You can try
label.text = words.first ?? "No words"
or
label.text = words.randomElement() ?? "No words"
words is an array of type String so you can't assign it directly to the text property of the label which is of type String

Swift 4 Replace word within String

The setup: A UITextField and a Tableview with suggested users
I try to have the following result:
I want users to be able to link other users.
Its working fine as long as I search with my last word in the array
let caption = captionTextView.text
let words = caption?.components(separatedBy: .whitespacesAndNewlines)
guard let searchingWord = words?.last else {return}
if searchingWord.hasPrefix("#") {
self.indicator.startAnimating()
let search = searchingWord.trimmingCharacters(in: CharacterSet.punctuationCharacters).lowercased()
}
But in case a user wants to adjust a username in the middle or at least not at the end of the array, the searching functions doesn't work properly as it still searches with the last word in the array
Example:
"Hey how are you #Lisa #Marcel #Thomas"
In case a user wants to change "#Lisa" to "#Lisbeth" the search function will search with Thomas as its the last word in the array
I wasn't able to get the word I am working at, only last and first words in the array, however I am able to get the current cursor location with
let cursor = captionTextView.cursorOffset!
which is an extension.
So how do I get the word I am working at up until the next "#" to the left und the next blank space to the right? Thanks in advance!
Maybe try something like this:
if let selectedRange = textview.selectedTextRange {
let cursorOffset = textview.offset(from: textview.beginningOfDocument, to: selectedRange.start)
let text = textview.text
let substring = text?.prefix(cursorOffset)
let editedWord = substring?.split(separator: "#")
}
(written on a phone, and untested)
One solution is Regular Expression
let string = "Hey how are you #Lisa #Marcel #Thomas"
let searchingWord = "Lisa"
let replacingWord = "Lisbeth"
let pattern = "#\(searchingWord)\\s"
string.replacingOccurrences(of: pattern, with: "#\(replacingWord) ", options: .regularExpression)
The pattern searches for # followed by the searching word followed by a whitespace character.
Since you say things are working the way you want if the last word is the one that has a username in it you just need to loop over all the words. Depending on your needs you may need to keep track of the usernames that were in the text before to save you from searching for the same user multiple times, but an array of used usernames should sort that for you.
Also, unless you want to prevent users from having underscores and the such in their names you should tweak the way in which you remove the # symbol as well.
guard let words = captionTextView.text?.components(separatedBy: .whitespacesAndNewlines) else { return }
for word in words where word.hasPrefix("#") {
self.indicator.startAnimating()
let search = word.replacingOccurrences(of: "#", with: "").lowercased()
}
Sticking the above code into a playground that uses the sample string you supplied in place of captionTextView.text? and printing search each time yielded…
lisa
marcel
thomas

UITableView SearchBar filtering inquiry

I have a very long tableView that I am able to search and filter results.
However, if I were to type the letter "i" as input,
all words with the letter "i" show up.
Is it possible to filter in a way so that the letter I type corresponds to the first letter of the word I want to filter.
For example my array ["should not use","Tristan","biscuit","is","should not use"]
and if I search the word "is"
, can that word automatically show up before the word "biscuit"?
Expected Result :
["is","biscuit","Tristan"]
You can use filter and sorted function to get the expected result.
import UIKit
var theArray: [String] = ["biscuit", "Tristan", "is", "iser", "instrument", "look"]
var keyword: String = "is"
let result = theArray
.filter { $0.contains(keyword) }
.sorted() { ($0.hasPrefix(keyword) ? 0 : 1) < ($1.hasPrefix(keyword) ? 0 : 1) }
print(result)
OUTPUT
["is", "iser", "biscuit", "Tristan"]

Convert array in quotation marks to just an array

I currently have a string, that's supposed to be an Array:
var content = "['A','B','C']"
//What I want -> var content = ['A', 'B', 'C']
I need to remove the quotation marks, so that it's just an Array, i.e. String to Array. How would one attempt that?
This looks similar to JSON syntax except that the single quotes should be double quotes.
Well then, let's just do that:
let source = "['A','B','C']"
Replace single quotes with double quotes:
let content = source.stringByReplacingOccurrencesOfString("'", withString: "\"")
Then convert the String to NSData (becomes valid JSON):
guard let data = content.dataUsingEncoding(NSUTF8StringEncoding) else { fatalError() }
Finally, convert the JSON data back to a Swift array of Strings:
guard let arrayOfStrings = try NSJSONSerialization.JSONObjectWithData(data, options: []) as? [String] else { fatalError() }
Result:
print(arrayOfStrings)
["A", "B", "C"]
print(arrayOfStrings[1])
"B"
Here's a semi-hacky solution to your specific example.
let content = "['A','B','C']"
var characters = content.characters
characters.removeFirst(2) // Remove ['
characters.removeLast(2) // Remove ']
let contentArray = String(characters).componentsSeparatedByString("','")
print(contentArray) // ["A", "B", "C"]
Disclaimer/Warning:
This solution isn't robust as it expects your array to only contain objects wrapped in ' characters. It will however work for any length of string (e.g. replacing A with foo will work).
If your actual content string is any more complex than what you have here then I would take Rob's advice and try JSON serialization (especially if this string comes from a place you don't control like the server).
You could do this one:
let arr = content.componentsSeparatedByCharactersInSet(NSCharacterSet (charactersInString: "['],")).filter({!$0.isEmpty})
Explanation:
First, we split the string into an array based upon separators like: [, ', ,, ]
We now have an array with some empty strings, we use filter() to remove them.
And Voila !
Warning:
like #nebs' warning, carefull with this solution. If your string is composed by more complexe strings (ex: "['Hello [buddy]', 'What's up?', 'This is a long text, or not?']"), especially string composed with the separators, you will get an array that will not match with your expected result.

Resources