@appzYourLife のソリューションの改善として、ネイティブ Swift でこれを行うことができますSet
。この場合、カウントされたセットは必ずしも必要ではないためです。これmap(_:)
により、各名前の文字を重ねて Objective-C に橋渡しする必要がなくなります。のように、一連の を使用できるようになりCharacter
ましたHashable
。
例えば:
struct Candy {
let name: String
}
let candies = [Candy(name: "CRAB"), Candy(name: "DUNGINESS"), Candy(name: "RAW")]
var filteredCandies = [Candy]()
func filterContentForSearchText(searchText: String) {
let searchCharacters = Set(searchText.lowercaseString.characters)
filteredCandies = candies.filter {Set($0.name.lowercaseString.characters).isSupersetOf(searchCharacters)}
tableView.reloadData()
}
filterContentForSearchText("RA")
print(filteredCandies) // [Candy(name: "CRAB"), Candy(name: "RAW")]
filterContentForSearchText("ED")
print(filteredCandies) // Candy(name: "DUNGINESS")]
また、これをパフォーマンスのボトルネックとして特定できるかどうかに応じて (最初にプロファイリングを行う必要があります)、「キャンディー」名の文字を含むセットをキャッシュすることで、上記をさらに最適化できる可能性があり、毎回それらを再作成する必要がなくなります。検索します (ただし、データを更新する場合は、それらが更新されていることを確認する必要がありますcandies
)。
検索するときは、対応するキャンディーを除外するためにzip(_:_:)
andを使用できます。flatMap(_:)
let candies = [Candy(name: "CRAB"), Candy(name: "DUNGINESS"), Candy(name: "RAW")]
// cached sets of (lowercased) candy name characters
let candyNameCharacterSets = candies.map {Set($0.name.lowercaseString.characters)}
var filteredCandies = [Candy]()
func filterContentForSearchText(searchText: String) {
let searchCharacters = Set(searchText.lowercaseString.characters)
filteredCandies = zip(candyNameCharacterSets, candies).flatMap {$0.isSupersetOf(searchCharacters) ? $1 : nil}
tableView.reloadData()
}