2015-12-29 4 views
9

Se il mio array principale è ["Hello","Bye","Halo"] e sto cercando "lo", filtrerà l'array solo su ["Hello", "Halo"].Filtro array di stringhe, inclusa la condizione "mi piace"

Questo è quello che ho provato:

let matchingTerms = filter(catalogNames) { 
     $0.rangeOfString(self.txtField.text!, options: .CaseInsensitiveSearch) != nil 
    } 

getta

Type of expression is ambiguous without more context 

Qualche suggerimento?

risposta

36

Uso contains invece:

let arr = ["Hello","Bye","Halo"] 
let filtered = arr.filter { $0.contains("lo") } 
print(filtered) 

uscita

[ "Ciao", "Halo"]

Grazie a @ user3441734 per aver ricordato che la funzionalità è ovviamente solo disponibile quando si import Foundation

+0

.. e non dimenticate di importazione Fondazione – user3441734

+0

impressionante, grazie. Dammi un paio di minuti prima che io possa risalire –

+0

@ user3441734 grazie, hai ragione su questo - dimentica sempre le importazioni perché sono già nel progetto. – luk2302

2

È inoltre necessario confrontare con NSNotFound. La documentazione per rangeOfString: opzioni: dice:

Una struttura NSRange che fornisce la posizione e la lunghezza nel ricevitore della prima occorrenza di aString, modulo le opzioni in maschera. Restituisce {NSNotFound, 0} se aString non viene trovato o è vuoto (@ "").

import Foundation 

let catalogNames = [ "Hats", "Coats", "Trousers" ] 

let matchingTerms = catalogNames.filter { 
    $0.rangeOfString(self.txtField.text!, options: .CaseInsensitiveSearch).location != NSNotFound 
} 
2

con l'aiuto di estensione String è possibile utilizzare una soluzione Swift puro (senza Foundation importazione). Non ho controllato la velocità, ma non dovrebbe essere peggiore come l'equivalente di base.

extension String { 
    func contains(string: String)->Bool { 
     guard !self.isEmpty else { 
      return false 
     } 
     var s = self.characters.map{ $0 } 
     let c = string.characters.map{ $0 } 
     repeat { 
      if s.startsWith(c){ 
       return true 
      } else { 
       s.removeFirst() 
      } 
     } while s.count > c.count - 1 
     return false 
    } 
} 

let arr = ["Hello","Bye","Halo"] 
let filtered = arr.filter { $0.contains("lo") } 

print(filtered) // ["Hello", "Halo"] 

"a".contains("alphabet") // false 
"alphabet".contains("") // true 
24

In Swift 3,0

let terms = ["Hello","Bye","Halo"] 

var filterdTerms = [String]() 


func filterContentForSearchText(searchText: String) { 
    filterdTerms = terms.filter { term in 
     return term.lowercased().contains(searchText.lowercased()) 
    } 
} 


filterContentForSearchText(searchText: "Lo") 
print(filterdTerms) 

uscita

["Hello", "Halo"] 
+1

Ha chiesto una rapida sintassi ** due **. Qual è il punto di fornire una risposta rapida3? – GhostCat

+5

Quando si cerca solo un array di stringhe di filtri, lui/lei otterrà una risposta e potrebbe aggiornare la conoscenza della sintassi nella versione aggiornata –

+6

Penso che sia stato richiesto per Swift 2, in questo caso era reale, ora stiamo lavorando con Swift 3 quindi è più prezioso per questo momento. – Resty

2

Il mio provare ...

let brands = ["Apple", "FB", "Google", "Microsoft", "Amazon"] 

let b = brands.filter{(x) -> Bool in 
(x.lowercased().range(of: "A".lowercased()) != nil) 
} 
print(b) //["Apple", "Amazon"] 
3

Swift 3,1

let catalogNames = [ "Hats", "Coats", "Trousers" ] 
let searchCatalogName = "Hats" 

let filteredCatalogNames = catalogNames.filter { catalogName in 
    return catalogName.localizedCaseInsensitiveContains(searchCatalogName) 
} 

print(filteredCatalogNames)