webentwicklung-frage-antwort-db.com.de

Verwenden von NSPredicate zum Filtern eines NSArray basierend auf NSDictionary-Schlüsseln

Ich habe eine Reihe von Wörterbüchern.

Ich möchte das Array anhand eines Schlüssels filtern.

Ich habe das versucht:

NSPredicate *predicate = [NSPredicate predicateWithFormat:@"(SPORT ==  %@)", @"Football"];

NSArray *filteredArray = [data filteredArrayUsingPredicate:predicate];

Das funktioniert nicht, ich bekomme keine Ergebnisse. Ich glaube, ich mache etwas falsch. Ich weiß, dass dies die Methode ist, wenn "SPORT" ein Ivar war. Ich denke, es ist wahrscheinlich anders, wenn es ein Schlüssel ist.

Ich konnte jedoch kein Beispiel finden.

Vielen Dank


Update

Ich fügte der gesuchten Zeichenfolge Zitate hinzu.

NSPredicate *predicate = [NSPredicate predicateWithFormat:@"(SPORT ==  '%@')", @"Football"];

Es funktioniert immer noch nicht.


Update 2

Ich habe es gelöst. Ich musste eigentlich die einzelnen Anführungszeichen entfernen, was dem Leitfaden zu widersprechen scheint.

Mein eigentliches Problem ist, dass ich ein verschachteltes Array hatte und die Wörterbücher nicht wirklich auswertete. Knochen Kopf bewegen.

94
Corey Floyd

Es sollte funktionieren - solange die Datenvariable tatsächlich ein Array ist, das ein Wörterbuch mit dem Schlüssel SPORT enthält

NSArray *data = [NSArray arrayWithObject:[NSMutableDictionary dictionaryWithObject:@"foo" forKey:@"BAR"]];    
NSArray *filtered = [data filteredArrayUsingPredicate:[NSPredicate predicateWithFormat:@"(BAR == %@)", @"foo"]];

Gefiltert enthält in diesem Fall das Wörterbuch. 

(Das% @ muss nicht in Anführungszeichen gesetzt werden. Dies erfolgt, wenn NSPredicate das Objekt erstellt.)

150
suraken

Ich weiß, dass es alte Nachrichten sind, aber meine zwei Cents hinzuzufügen. Standardmäßig verwende ich die Befehle LIKE[cd] und nicht nur [c]. Der [d] vergleicht Buchstaben mit Akzentzeichen. Dies funktioniert besonders gut in meiner Warcraft-App, wo Leute ihren Namen "Vòódòó" buchstabieren, was es fast unmöglich macht, ihren Namen in einer Tabellenansicht zu suchen. Die [d]-Zeichen entfernen ihre Akzentzeichen während des Prädikats. Ein Prädikat @"name LIKE[CD] %@", object.name, wobei object.name == @"voodoo" das Objekt zurückgibt, das den Namen Vòódòó enthält.

Aus der Apple-Dokumentation: Wie [cd] bedeutet "case- und diakritisch-insensitiv wie.". Eine vollständige Beschreibung der String-Syntax und eine Liste aller verfügbaren Operatoren finden Sie unter Predicate) Formatierungsstringsyntax .

27
ChargedNeuron
#import <Foundation/Foundation.h>
// clang -framework Foundation Siegfried.m 
    int
main() {
    NSArray *arr = @[
        @{@"1" : @"Fafner"},
        @{@"1" : @"Fasolt"}
    ];
    NSPredicate *p = [NSPredicate predicateWithFormat:
        @"SELF['1'] CONTAINS 'e'"];
    NSArray *res = [arr filteredArrayUsingPredicate:p];
    NSLog(@"Siegfried %@", res);
    return 0;
}

NSPredicate ist nur in iPhone 3.0 verfügbar. 

Sie werden das erst bemerken, wenn Sie versuchen, auf dem Gerät auszuführen.

3
Rod

Wenn Sie mit Swift 3 ein Array von Wörterbüchern mit einem Vergleichselement basierend auf Wörterbuchschlüsseln und Werten filtern möchten, können Sie eines der folgenden Muster auswählen.


# 1. NSPredicateinit(format:arguments:) Initialisierung verwenden

Wenn Sie aus Objective-C stammen, bietet init(format:arguments:) einen Schlüsselwertcodierungsstil zur Bewertung Ihres Prädikats.

Verwendungszweck:

import Foundation

let array = [["key1": "value1", "key2": "value2"], ["key1": "value3"], ["key3": "value4"]]

let predicate = NSPredicate(format: "key1 == %@", "value1")
//let predicate = NSPredicate(format: "self['key1'] == %@", "value1") // also works
let filteredArray = array.filter(predicate.evaluate)

print(filteredArray) // prints: [["key2": "value2", "key1": "value1"]]

# 2. NSPredicateinit(block:) Initialisierung verwenden

Alternativ, wenn Sie strong typed APIs gegenüber stringly typed APIs bevorzugen, können Sie init(block:) initializer verwenden.

Verwendungszweck:

import Foundation

let array = [["key1": "value1", "key2": "value2"], ["key1": "value3"], ["key3": "value4"]]

let dictPredicate = NSPredicate(block: { (obj, _) in
    guard let dict = obj as? [String: String], let value = dict["key1"] else { return false }
    return value == "value1"
})

let filteredArray = array.filter(dictPredicate.evaluate)
print(filteredArray) // prints: [["key2": "value2", "key1": "value1"]]
0
Imanou Petit