2017-10-19 151 views
0

我有一個UITableView和一個UISearchController。我想根據UISearchBar.textNSPredicate過濾我的數據數組(名爲allGames)。根據NSPredicate篩選結構數組SWIFT

我的代碼只能過濾字符串數組是這樣的:

func updateSearchResults(for searchController: UISearchController) { 

    filteredGames.removeAll(keepingCapacity: false) 

    let searchPredicate = NSPredicate(format: "SELF CONTAINS[c] %@", searchController.searchBar.text!) 
    let array = (allGames).filtered(using: searchPredicate) 

    filteredGames = array as! [String] 

    self.tableView.reloadData() 
} 

這裏我過濾陣列。但是,如果我創建此結構:

struct Games { 

    var name: String? 
    var type: String? 
    var image: UIImage? 
} 

如何根據遊戲名稱和類型過濾數組?在此先感謝您的幫助。

+0

[搜索欄Swift 3 - 不能在/包含運算符與集合中使用]的可能重複(https://stackoverflow.com/questions/41308007/search-bar-swift-3-cant-use-in- contains-operator-with-collection) - 不能將NSPredicate與結構數組一起使用。 –

+0

另請參見[Swift - 使用UISearchController和NSPredicate使用結構數組搜索](https://stackoverflow.com/questions/32556328/swift-search-using-uisearchcontroller-and-nspredicate-with-an-array-of-結構體)或[在swift中搜索結構體](https://stackoverflow.com/questions/34360226/search-for-struct-in-swift)。 –

+0

哦,我讀了很多問題,沒有找到這些問題! –

回答

2

假設allGames是一個數組[Games] - 由結構應該以單數形式Game具名的方式 - 我強烈建議使用本地斯威夫特filter功能

let searchText = searchController.searchBar.text! 
let fileredGames = allGames.filter { $0.name?.range(of: searchText, options: [.caseInsensitive]) != nil 
            || $0.type?.range(of: searchText, options: [.caseInsensitive]) != nil } 

也考慮申報typename在結構中是非可選的。

+0

它看起來很好。我將我的數組allGames命名爲與filteredGames不同。你的意思是在我的結構中創建啓動的變量更好?像'let name:String =「」'? –

+0

不,一般的誤解。許多人的意思是(並在教程中提出),如果沒有初始化器,你不能聲明屬性是非可選的(沒有感嘆號或問號)。這在類的情況下是正確的,但是在struct **中,您可以**,因爲存在隱式的成員初始化程序。如果該值不應該被改變,你甚至可以聲明該屬性爲常量'let name:String'。 – vadian