2017-10-19 42 views
0

J'ai un UITableView et un UISearchController. Je veux filtrer mon tableau de données (nommé: allGames) selon le NSPredicate du UISearchBar.text.Filtrer un tableau struct selon un NSPredicate SWIFT

Mon code filtre seulement un tableau de chaîne comme ceci:

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() 
} 

Ici, je peux filtrer mon tableau. Mais si je crée cette structure:

struct Games { 

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

Comment puis-je filtrer la matrice en fonction des noms et des types de jeu? Merci d'avance pour votre aide.

+0

Possible duplication de [Barre de recherche Swift 3 - Ne peut pas utiliser dans/contient opérateur avec collection] (https://stackoverflow.com/questions/41308007/search-bar-swift-3-cant-use-in- contains-operator-with-collection) - Vous ne pouvez pas utiliser NSPredicate avec un tableau de structures. –

+0

Voir aussi [Swift - Recherche en utilisant UISearchController et NSPredicate avec un tableau de structures] (https://stackoverflow.com/questions/32556328/swift-search-using-uisearch-controller-and-nspredicate-with-an-array-of- structs) ou [Recherche de struct dans swift] (https://stackoverflow.com/questions/34360226/search-for-struct-in-swift). –

+0

Oh j'ai lu beaucoup de questions et je n'ai pas trouvé ces questions! –

Répondre

2

En supposant allGames est un tableau [Games] - par la façon dont le struct est censé être nommé au singulier Game - Je recommande fortement d'utiliser la fonction native Swift 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 } 

Tenir compte également de déclarer type et name dans la structure comme non-optionnel.

+0

On dirait que ça fonctionne bien. J'ai nommé mon tableau allGames pour faire la différence avec filteredGames. Vous voulez dire qu'il est préférable de créer des variables initiées dans ma structure? Comme 'let name: String =" "'? –

+0

Non, il y a un malentendu général. Beaucoup de gens signifient (et suggèrent dans les tutoriels) que vous ne pouvez pas déclarer les propriétés non optionnelles (pas d'exclamation ou de point d'interrogation) sans un initialiseur. C'est correct dans le cas d'une classe, mais dans une structure ** vous pouvez ** parce qu'il y a l'initialiseur implicite de memberwise. Vous pouvez même déclarer la propriété comme constante 'let name: String' si la valeur est supposée ne pas être modifiée. – vadian