2015-04-04 19 views
8

Ich habe Probleme hatte Filterung Array von Schlüsselwörtern (Strings) in schnellen, Mein Code:Swift Filter Array von Strings

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

Als AnyObject nicht Subtyp von NSString sein kann, bin ich mit diesem fest!

+0

Was ist der genaue Fehler, den Sie bekommen? Was wird gedruckt, wenn Sie NSLog ("\ (keywords)") '? – Undo

+0

Bitte beachten Sie, dass Sie ein optionales zurückgeben. Hoffe, das hilft –

+0

es führt es nicht gibt mir den oben genannten Fehler: "AnyObject ist kein Untertyp von NSString" – Meseery

Antwort

16

[Updated für Swift 2.0]

Als NSString ist gebührenfrei zu Swift überbrückt String, nur zu vermeiden, die Nötigungen mit:

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

Aber, wenn Sie denken, allValues sind keine Strings:

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

, die ein optionales Array zurückgibt.

4

Ihre filter ist über [AnyObject], aber Ihre Schließung dauert NSString. Diese müssen übereinstimmen. Außerdem muss Ihr Ergebnis ein Bool sein, kein Bool?. Sie können diese einfach so ansprechen:

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

Dieser übernimmt AnyObject und dann versucht, es zu NSString zu zwingen, nach unten. Es ist dann Null-Coalleces (??) das Ergebnis, um sicherzustellen, dass es immer ein Bool ist.

Ich würde jedoch empfehlen, keywords als [String:String] eher als NSDictionary zu behandeln. Das würde alle Komplikationen von AnyObject loswerden. Dann können Sie einfach tun:

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

Wann immer möglich, konvertieren Foundation Sammlungen in Swift Sammlungen so schnell wie möglich und diejenigen zu speichern. Wenn Sie ankommende Foundation Objekte haben, können Sie in der Regel wandeln sie leicht mit Techniken wie:

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

Oder Sie können die folgende tun, um sie zu konvertieren, so dass sie im Debug-Absturz werden (aber leise „Arbeit“ in Release) :

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

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

Es ist sowohl ein Problem mit GoZoner Antwort für bestimmte Datentypen und auch eine etwas bessere Art und Weise, dies zu tun. Die folgenden Beispiele können dies zeigen:

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] 

Wahrscheinlich nicht die Menge, die Sie erwartet haben!

Doch das funktioniert gut auf diese Weise, wenn wir geben animalArray als NSMutableArray nicht:

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

filteredAnimals: [Otter, Deer] 

Allerdings würde ich empfehlen $ 0.contains() anstelle von $ 0.rangeOfString() verwenden! = null, weil es in beiden Fällen funktioniert und die Lesbarkeit des Codes leicht verbessert:

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

filteredAnimals: [Otter, Deer]