Verwenden von Prädikat in Swift


93

Ich arbeite hier an dem Tutorial (Swift lernen) für meine erste App: http://www.appcoda.com/search-bar-tutorial-ios7/

Ich stecke in diesem Teil fest (Objective-C-Code):

- (void)filterContentForSearchText:(NSString*)searchText scope:(NSString*)scope
{
    NSPredicate *resultPredicate = [NSPredicate predicateWithFormat:@"name contains[c]         %@", searchText];
    searchResults = [recipes filteredArrayUsingPredicate:resultPredicate];
}

Kann jemand raten, wie man ein Äquivalent für NSPredicate in Swift erstellt?

Antworten:


157

Dies ist wirklich nur ein Syntaxschalter. OK, wir haben also diesen Methodenaufruf:

[NSPredicate predicateWithFormat:@"name contains[c] %@", searchText];

In Swift, Bauer überspringt den „blahWith ...“ Teil und verwendet nur die Klassennamen als Funktion und dann auf die Argumente geht gerade, so [NSPredicate predicateWithFormat: …]würde NSPredicate(format: …). (Für ein anderes Beispiel [NSArray arrayWithObject: …]würde werden NSArray(object: …). Dies ist ein reguläres Muster in Swift.)

Jetzt müssen wir nur noch die Argumente an den Konstruktor übergeben. In Objective-C sehen NSString-Literale so aus @"", aber in Swift verwenden wir nur Anführungszeichen für Zeichenfolgen. Das gibt uns also:

let resultPredicate = NSPredicate(format: "name contains[c] %@", searchText)

Und genau das brauchen wir hier.

(Im Übrigen werden Sie feststellen, dass einige der anderen Antworten stattdessen eine Formatzeichenfolge wie verwenden "name contains[c] \(searchText)". Dies ist nicht korrekt. Dies verwendet eine Zeichenfolgeninterpolation, die sich von der Prädikatformatierung unterscheidet und für diese im Allgemeinen nicht funktioniert.)


Vielen Dank. Du rettest mich eines Tages!
Hugo

2
Um die zweite Zeile Ihrer Methode anzusprechen, können Sie das Prädikat wie searchResults = recipes.filter { resultPredicate.evaluateWithObject($0) }
Ben Packard

43

Ich arbeite ziemlich lange mit Prädikaten. Hier ist meine Schlussfolgerung (SWIFT)

//Customizable! (for me was just important if at least one)
request.fetchLimit = 1


//IF IS EQUAL

//1 OBJECT
request.predicate = NSPredicate(format: "name = %@", txtFieldName.text)

//ARRAY
request.predicate = NSPredicate(format: "name = %@ AND nickName = %@", argumentArray: [name, nickname])


// IF CONTAINS

//1 OBJECT
request.predicate = NSPredicate(format: "name contains[c] %@", txtFieldName.text)

//ARRAY
request.predicate = NSPredicate(format: "name contains[c] %@ AND nickName contains[c] %@", argumentArray: [name, nickname])

1
Was ist gleich mit LIKE 'a%z'?
TomSawyer

@ Jiří Zahálka Was bedeutet Anfrage hören?
Muju

28

Beispiel für die Verwendung in Swift 2.0

let dataSource = [
    "Domain CheckService",
    "IMEI check",
    "Compliant about service provider",
    "Compliant about TRA",
    "Enquires",
    "Suggestion",
    "SMS Spam",
    "Poor Coverage",
    "Help Salim"
]
let searchString = "Enq"
let predicate = NSPredicate(format: "SELF contains %@", searchString)
let searchDataSource = dataSource.filter { predicate.evaluateWithObject($0) }

Sie erhalten (Spielplatz)

Geben Sie hier die Bildbeschreibung ein


Was ist, wenn ... wenn ich eine Reihe von Wörterbüchern habe? Wie analysiere ich, um die Daten zu erhalten?
Revathy Durairajan

1
@RevathyDurairajan Sie benötigen SELF.yourkeyname, um eine Reihe von Wörterbüchern zu filtern.
Pawan Rai

11

Sie können in Swift verfügbare Filter verwenden, um Inhalte aus einem Array zu filtern, anstatt ein Prädikat wie in Objective-C zu verwenden.

Ein Beispiel in Swift 4.0 lautet wie folgt:

var stringArray = ["foundation","coredata","coregraphics"]
stringArray = stringArray.filter { $0.contains("core") }

Da im obigen Beispiel jedes Element im Array eine Zeichenfolge ist, können Sie die containsMethode zum Filtern des Arrays verwenden.

Wenn das Array benutzerdefinierte Objekte enthält, können die Eigenschaften dieses Objekts verwendet werden, um die Elemente auf ähnliche Weise zu filtern.


6

Verwenden Sie den folgenden Code:

 func filterContentForSearchText(searchText:NSString, scopes scope:NSString)
{
    //var searchText = ""

    var resultPredicate : NSPredicate = NSPredicate(format: "name contains[c]\(searchText)", nil)

    //var recipes : NSArray = NSArray()

    var searchResults = recipes.filteredArrayUsingPredicate(resultPredicate)
}

1
Aus irgendeinem Grund hat es für mich nicht funktioniert, es so zu schreiben, aber myPredicateString = "name enthält [c] (searchText)" und dann var resultPredicate: NSPredicate = NSPredicate (Format: myPredicateString)
AppHandwerker

5

Ich denke, dies wäre ein besserer Weg, dies in Swift zu tun:

func filterContentForSearchText(searchText:NSString, scope:NSString)
{
   searchResults = recipes.filter { name.rangeOfString(searchText) != nil  }
}

1
Dies ist idiomatischer, wenn Sie a filtern Sequence, aber es gibt Fälle, in denen Sie a benötigen NSPredicate, wie beim Umgang mit NSFetchedResultsController.
Jarsen

1

In rascher 2.2

func filterContentForSearchText(searchText: String, scope: String) {
    var resultPredicate = NSPredicate(format: "name contains[c]         %@", searchText)
    searchResults = (recipes as NSArray).filteredArrayUsingPredicate(resultPredicate)
}

In schnellem 3.0

func filterContent(forSearchText searchText: String, scope: String) {
        var resultPredicate = NSPredicate(format: "name contains[c]         %@", searchText)
        searchResults = recipes.filtered(using: resultPredicate)
    }

1

// ändere "Name" und "Wert" entsprechend deinen Array-Daten.

// Ändern Sie den Namen "yourDataArrayName" für Ihr Array (NSArray).

    let resultPredicate = NSPredicate(format: "SELF.name contains[c] %@", "value")

    if let sortedDta = yourDataArrayName.filtered(using: resultPredicate) as? NSArray {

 //enter code here.

        print(sortedDta)
    }
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.