2015-11-19 5 views
5

Sto creando una barra di ricerca per la mia app. Sto usando il metodo filter per ottenere i risultati. Voglio cercare tra più chiavi.Filtro rapido per più tasti del dizionario

Array di dizionari:

var people = [ 
       ["First": "John", "Last": "Doe"], 
       ["First": "Steve", "Last": "Jobs"], 
       ["First": "Elon", "Last": "Musk"] 
      ] 

io sono solo in grado di cercare sia "In primo luogo" o "Last", ma non entrambi, con questo codice:

searchResults = people.filter{ 
      var string = $0["Last"] 
      // or "First" 

      string = string?.lowercaseString 

      return string!.rangeOfString(searchText.lowercaseString) != nil 
     } 
+0

È questo il codice reale che stai utilizzando? Ti manca un '' 'dopo' Steve' nella seconda riga della tua serie di dizionari – Undo

+0

Il dizionario che sto usando è molto grande quindi ne ho fatto uno piccolo come esempio, ma il codice per la ricerca è quello che ho sto usando. –

risposta

7

Un approccio potrebbe essere per confrontare semplicemente entrambi i campi per la stringa di ricerca:

var people = [ 
    ["First": "JohnMusk", "Last": "Doe"], 
    ["First": "Steve", "Last": "Jobs"], 
    ["First": "Elon", "Last": "Musk"] 
] 

var searchText = "Musk" 

var searchResults = people.filter{ 
     var firstName = $0["First"]!.lowercaseString 
     var lastName = $0["Last"]!.lowercaseString 

     return firstName.rangeOfString(searchText.lowercaseString) != nil 
       || lastName.rangeOfString(searchText.lowercaseString) != nil 

} 

questo mi dà questo risultato:

2015-11-18 18:19:47.691 MyPlayground[36558:7031733] (
     { 
     First = JohnMusk; 
     Last = Doe; 
    }, 
     { 
     First = Elon; 
     Last = Musk; 
    } 
) 

Quale credo sia quello che vuoi.

1

Il seguente codice dovrebbe opere:

var people = [ 
     ["First": "John", "Last": "Doe"], 
     ["First": "Steve", "Last": "Jobs"], 
     ["First": "Elon", "Last": "Musk"] 
     ] 


    let searchResults = people.filter{ 

    var found = false 
    let searText = "Elon" 
    for str in $0.values { 
     found = str.lowercaseString.rangeOfString(searText.lowercaseString) != nil 
     if found { 
      break 
     } 
    } 
    return found 
} 
4

Ecco un approccio alternativo utilizzando NSPredicate. NSPredicate ha un potente syntax che può fare alcune cose carine per te.

let firstNameQuery = "jo" 
let lastNameQuery = "mus" 
// [cd] means case/diacritic insensitive. %K is used to pass in key names since FIRST and LAST are reserved keywords in NSPredicate 
let predicate = NSPredicate(format: "%K CONTAINS[cd] %@ OR %K CONTAINS[cd] %@", "First", firstNameQuery, "Last", lastNameQuery) 
let sorted = people.filter({ 
    return predicate.evaluateWithObject($0) 
}) 
// sorted would contain John Doe and Elon Musk entries 

Nel mio esempio ho passato in diverse query di ricerca per il nome e il cognome, ma si poteva, ovviamente, passare nella stessa query per entrambi. Dimostra solo il potere di questo approccio.