wake-up-neo.net

Schnelle Filteranordnung von Zeichenfolgen

Ich habe Probleme beim Filtern von Schlüsselwortreihen (Strings) in Swift. Mein Code:

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

Da AnyObject kein Untertyp von NSString sein kann, bleibe ich dabei!

9
Meseery

Swift 4.2 bietet eine neue Möglichkeit, dies zu tun:

var theBigLebowski = ["The Dude", "Angry Walter", "Maude Lebowski", "Donny Kerabatsos", "The Big Lebowski", "Little Larry Sellers"]

// after removeAll -> ["The Dude", "Angry Walter", "Donny Kerabatsos", "Little Larry Sellers"]
theBigLebowski.removeAll{ $0.contains("Lebowski")}
print(theBigLebowski)
1
Adrian

[Aktualisiert für Swift 2.0]

Da NSString gebührenfrei mit Swift String verbunden ist, vermeiden Sie einfach die Zwänge mit:

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

Aber wenn Sie denken, dass allValues keine Zeichenketten sind:

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

dies gibt ein optionales Array zurück.

16
GoZoner

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

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

Dies akzeptiert AnyObject und versucht dann, es auf NSString zu reduzieren. Dann wird das Ergebnis mit null (??) verglichen, um sicherzustellen, dass es sich immer um eine Bool handelt.

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

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

Konvertieren Sie nach Möglichkeit Foundation-Sammlungen so schnell wie möglich in Swift-Sammlungen und speichern Sie diese. Wenn Sie eingehende Foundation-Objekte haben, können Sie diese im Allgemeinen einfach mit folgenden Techniken konvertieren:

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

Oder Sie können die folgenden Schritte ausführen, um sie so zu konvertieren, dass sie beim Debuggen abstürzen (im Release jedoch unbemerkt "funktionieren"):

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

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

Es gibt sowohl ein Problem mit der GoZoner-Antwort für bestimmte Datentypen als auch einen etwas besseren Weg, 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 das Set, das Sie erwartet haben!

Dies funktioniert jedoch problemlos, wenn animalArray nicht als NSMutableArray eingegeben wird:

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

filteredAnimals: [Otter, Deer]

Ich würde jedoch empfehlen, $ 0.contains () anstelle von $ 0.rangeOfString ()! = Nil zu verwenden, da dies unter beiden Umständen funktioniert und die Lesbarkeit des Codes geringfügig verbessert:

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

filteredAnimals: [Otter, Deer]
0
Ryan Davis