2015-04-04 18 views
8

miałem kłopoty filtrowania tablicę słów kluczowych (łańcuchy) w szybkich, Mój kod:Swift filtr tablica ciągów

self.filteredKeywords=filter(keywords.allValues, {(keyword:NSString) ->            
    Bool in 
    let words=keyword as? NSString 
    return words?.containsString(searchText) 
    }) 

Jak AnyObject nie może być podtypem NSString, utknąłem z tym!

+0

Jaki jest dokładny błąd? Co jest drukowane, jeśli spróbujesz 'NSLog (" \ (słowa kluczowe) ")'? – Undo

+0

Zauważ, że zwracasz opcjonalne. Mam nadzieję, że to pomoże –

+0

to nie działa daje mi błąd wspomniany powyżej: "AnyObject nie jest podtypem NSString" – Meseery

Odpowiedz

16

[Aktualizacja dla Swift 2.0]

Jak NSString jest bezpłatny mostem Swift String, po prostu uniknąć coercions z:

3> ["abc", "bcd", "xyz"].filter() { nil != $0.rangeOfString("bc") } 
$R1: [String] = 2 values { 
    [0] = "abc" 
    [1] = "bcd" 
} 

Ale jeśli myślisz allValues nie są ciągi:

(keywords.allValues as? [String]).filter() { nil != $0.rangeOfString("bc") } 

która zwraca opcjonalną tablicę.

4

Twoja filter jest ponad [AnyObject], ale zamknięcie trwa NSString. Te muszą pasować. Twój wynik musi być równy Bool, a nie Bool?. Można rozwiązać to po prostu tak:

self.filteredKeywords = filter(keywords.allValues, { 
    let keyword = $0 as? NSString 
    return keyword?.containsString(searchText) ?? false 
}) 

Ten akceptuje AnyObject a następnie próbuje zmusić go do NSString. Następnie zeruje się (??) wynik, aby upewnić się, że zawsze jest to Bool.

Polecam jednak, traktując keywords jako [String:String] zamiast NSDictionary. To by pozbyć się wszystkich komplikacji z AnyObject. Następnie można po prostu to zrobić:

self.filteredKeywords = keywords.values.filter { $0.rangeOfString(searchText) != nil } 

miarę możliwości konwertowania zbiorów Fundacji w kolekcjach Swift tak szybko, jak to tylko możliwe i przechowywania tych. Jeśli masz przychodzących obiektów Foundation, można łatwo przekonwertować je na ogół z technik, takich jak:

let dict = nsdict as? [String:String] ?? [:] 

Albo można wykonać następujące czynności, aby przekształcić je w taki sposób, będą one rozbijają w debugowania (ale cicho „pracę” w wydaniu) :

func failWith<T>(msg: String, value: T) -> T { 
    assertionFailure(msg) 
    return value 
} 

let dict = nsdict as? [String:String] ?? failWith("Couldn't convert \(d)", [:]) 
0

Istnieje zarówno problem z odpowiedzią GoZoner jest dla niektórych typów danych, a także nieco lepszy sposób to zrobić. Poniższe przykłady mogą to pokazać:

let animalArray: NSMutableArray = ["Dog","Cat","Otter","Deer","Rabbit"] 
let filteredAnimals = animalArray.filter { $0.rangeOfString("er") != nil } 
print("filteredAnimals:", filteredAnimals) 

filteredAnimals: [Dog, Cat, Otter, Deer, Rabbit] 

Prawdopodobnie nie taki zestaw, jakiego się spodziewałeś!

Jednak to działa prawidłowo w ten sposób, jeśli nie wpisz animalArray jako NSMutableArray:

let animalArray = ["Dog","Cat","Otter","Deer","Rabbit"] 
let filteredAnimals = animalArray.filter { $0.rangeOfString("er") != nil } 
print("filteredAnimals:", filteredAnimals) 

filteredAnimals: [Otter, Deer] 

Jednak polecam korzystania $ 0.contains() zamiast $ 0.rangeOfString()! = nil ponieważ działa w obu przypadkach i nieznacznie poprawia czytelność kodu:

let animalArray: NSMutableArray = ["Dog","Cat","Otter","Deer","Rabbit"] 
let filteredAnimals = animalArray.filter { $0.contains("er") } 
print("filteredAnimals:", filteredAnimals) 

filteredAnimals: [Otter, Deer] 
Powiązane problemy