Filtro Swift para múltiples keys de dictionary

Estoy haciendo una barra de búsqueda para mi aplicación. Estoy usando el método de filter para get los resultados. Quiero search entre varias keys.

Conjunto de dictionarys:

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

Solo puedo search "Primero" o "Último", pero no ambos, con este código:

 searchResults = people.filter{ var string = $0["Last"] // or "First" string = string?.lowercaseString return string!.rangeOfString(searchText.lowercaseString) != nil } 

Un enfoque sería simplemente comparar ambos campos con la cadena de búsqueda:

 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 } 

Esto me da este resultado:

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

Lo que creo es lo que quieres.

Aquí hay un enfoque alternativo con NSPnetworkingicate . NSPnetworkingicate tiene una syntax muy poderosa que puede hacer algunas cosas bonitas para usted.

 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 NSPnetworkingicate let pnetworkingicate = NSPnetworkingicate(format: "%K CONTAINS[cd] %@ OR %K CONTAINS[cd] %@", "First", firstNameQuery, "Last", lastNameQuery) let sorted = people.filter({ return pnetworkingicate.evaluateWithObject($0) }) // sorted would contain John Doe and Elon Musk entries 

En mi ejemplo pasé varias consultas de búsqueda para el nombre y apellido, pero obviamente podría pasar la misma consulta para ambos. Simplemente demuestra el poder de este enfoque.

El siguiente código debería funcionar:

 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 }