问题
I currently have a UITextField
where I can enter a search string and it will return any of the strings in an array that contain that text, in that specific order. However, I want to make it possible to search on every word and ignore the order of the strings in the array.
var results = [String]()
let filterArray = ["Big green bubble", "Red bubble", "A bubble in green", "Small green bubble", "This bubble is green"]
let textString = "green bubble"
for i in 0 ..< filterArray.count {
let checkString = filterArray[i]
let filterRange = (checkString as NSString).range(of: textString, options: .caseInsensitive)
if filterRange.location != NSNotFound {
results.append(checkString)
}
}
print(results) // returns ["Big green bubble", "Small green bubble"]
I wish it would also include "A bubble in green" and "This bubble is green", because it contains every word I am searching for. Any ideas?
回答1:
Just filter elements from filterArray
which contains both of these words
let filterArray = ["Big green bubble", "Red bubble", "A bubble in green", "Small green bubble", "This bubble is green"]
let textString = "green bubble".lowercased()
let words = textString.components(separatedBy: " ")
let results = filterArray.map { $0.lowercased() }.filter { string in words.allSatisfy { string.components(separatedBy: " ").contains($0) } }
print(results) /* ["Big green bubble", "A bubble in green", "Small green bubble", "This bubble is green"] */
回答2:
You can use a set and check if the intersection count is equal to the number of words in the query:
let filterArray = ["Big green bubble", "Red bubble", "A bubble in green", "Small green bubble", "This bubble is green"]
let textString = "green bubble"
let wordsSet = Set(textString.components(separatedBy: " "))
let queryResult = filterArray.filter {
Set($0.components(separatedBy: " ")).intersection(wordsSet).count == wordsSet.count
}
queryResult // "Big green bubble", "A bubble in green", "Small green bubble", "This bubble is green"]
If you need case insensitive you can map all the words to lowercase:
let wordsSet = Set(textString.lowercased().components(separatedBy: " "))
let queryResult = filterArray
.map { $0.lowercased() }
.filter {
Set($0.components(separatedBy: " "))
.intersection(wordsSet).count == wordsSet.count
}
来源:https://stackoverflow.com/questions/54206910/search-for-multiple-words-ignoring-the-order-in-swift