Reputation: 36640
I have a situation where a value contains multiple fields, and provide a search bar where a user may enter phrases that could be split between those fields.
The following is a short sample from a playground illustrating what I would like to accomplish.
import Foundation
struct Item {
let name: String
let size: String
}
let itemA = Item(name: "stuff", size: "Large")
let itemB = Item(name: "something", size: "X-Large")
let items = [itemA, itemB]
let singleSearch = "stuff"
let singleFound = items.filter { $0.name.localizedStandardContains(singleSearch) ||
$0.size.localizedStandardContains(singleSearch)
}
print(singleFound) // ItemA
let multiSearch = "stuff large"
let multiFound = items.filter { $0.name.localizedStandardContains(multiSearch) ||
$0.size.localizedStandardContains(multiSearch)
}
print(multiFound) // Nothing found, expect to see itemA
Also, it has to be able to handle partial words as a user searches, to support winnowing down visible options.
let partialSearch = "stuff l"
let partialFound = items.filter { $0.name.localizedStandardContains(partialSearch) ||
$0.size.localizedStandardContains(partialSearch)
}
print(partialFound) // Nothing found, expect to see itemA
I suspect I may need to split the search term up into an array and process each word individually and see what the result is from the combined check. My concern is that the actual implementation has far more fields, so this could be impractical.
Upvotes: 0
Views: 63
Reputation: 11039
As a fast solution you can do following:
let multiSearch = "st la"
let trimmed = multiSearch.trimmingCharacters(in: .whitespacesAndNewlines)
let multiSearchComponents = trimmed.components(separatedBy: " ")
var filtered = items
multiSearchComponents.forEach { searchTerm in
filtered = filtered.filter { item in
item.name.localizedStandardContains(searchTerm) || item.size.localizedStandardContains(searchTerm)
}
}
print(filtered) //Prints itemA
Upvotes: 1