Reputation: 165
I want to type in a UISearchBar 2 Strings.
For ex. bob man
.
let itemArray: [searchItem] = [
searchItem(title: "Bob", subtitle: "Man"),
searchItem(title: "Bob", subtitle: "Woman"),
searchItem(title: "Joe", subtitle: "Man")
]
var filteredArray = [searchItem]()
How can I make sure I get the follow searchItem
back:
Only searchItem(title: "Bob", subtitle: "Man")
because only that matches bob
AND man
.
When you would search for only bob
you would get 2 items back:
searchItem(title: "Bob", subtitle: "Man"),
searchItem(title: "Bob", subtitle: "Woman")
The code I already have:
filteredArray = itemArray.filter { obj in
obj.title.lowercased().contains(searchBarText.lowercased()) ||
obj.subtitle.lowercased().contains(searchBarText.lowercased())
}
Upvotes: 1
Views: 91
Reputation: 1770
I did find a solution, sure it's not the best in case of performance, but you can go from here and improve my answer.
I test it in Playground
, i did leave some comments, if you need more information let me know, here is a simple code:
import Foundation
struct SearchItem {
let title: String
let subtitle: String
}
/// Trim white spaces from start and end, and map all words to lowercase
let searchedWords = "Bob man woman"
.trimmingCharacters(in: .whitespacesAndNewlines)
.components(separatedBy: " ")
.map { $0.lowercased() }
let itemArray: [SearchItem] = [
SearchItem(title: "Bob", subtitle: "Woman"),
SearchItem(title: "Joe", subtitle: "Man"),
SearchItem(title: "Bob", subtitle: "Man")
]
/// Lowercase all itemArray
let lowercasedItems = itemArray
.map { SearchItem(title: $0.title.lowercased(), subtitle: $0.subtitle.lowercased()) }
/// First trying to find best result which is contains both `title` and `subtitle`
var filteredArray = lowercasedItems
.filter { searchedWords.contains($0.title) && searchedWords.contains($0.subtitle) }
/// `filteredArray.isEmpty == false`, then we didn't find best result which contains both `title` and `subtitle`
/// `filteredArray.isEmpty == true` then we'll try to find at least one match
if filteredArray.isEmpty {
filteredArray = lowercasedItems
.filter { searchedWords.contains($0.title) || searchedWords.contains($0.subtitle) }
}
print(searchedWords)
print(filteredArray)
Hope this will help you!
Upvotes: 1