Search for multiple words ignoring the order in Swift

拈花ヽ惹草 提交于 2021-01-29 07:25:36

问题


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

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!