2012-06-11 8 views
10

Ich habe NSDictionary folgende NSArray (e) enthalten:NSPredicate Verwendung auf mehreren Tasten filtern basiert (NOT-Werte für Schlüssel)

NSArray *data = [[NSArray alloc] initWithObjects: 
       [NSDictionary dictionaryWithObjectsAndKeys:[NSNumber numberWithInt:1], @"bill", [NSNumber numberWithInt:2], @"joe", nil], 
       [NSDictionary dictionaryWithObjectsAndKeys:[NSNumber numberWithInt:3], @"bill", [NSNumber numberWithInt:4], @"joe", [NSNumber numberWithInt:5], @"jenny", nil], 
       [NSDictionary dictionaryWithObjectsAndKeys:[NSNumber numberWithInt:6], @"joe", [NSNumber numberWithInt:1], @"jenny", nil], 
       nil]; 

ich ein gefiltertes NSArray erstellen bin zu wollen, dass nur Objekte enthält, wo die NSDictionary passt mehrere 'Schlüssel' mit NSPredate an.

Zum Beispiel:

  • Filter des Array, um nur die NSDictionary Objekte enthält, die Tasten "Bill" und "Joe" haben [gewünschtes Ergebnis: neue NSArray enthalten würden die ersten zwei NSDictionary Objekte]
  • Filter das Array, um nur die NSDictionary Objekte enthält, die Tasten „Joe“ und „Jenny“ haben [gewünschtes Ergebnis: neue NSArray enthalten würden die letzten zwei NSDictionary Objekte]

Kann jemand bitte das Format des NSPredicate erklären, um dies zu erreichen?

Edit: Ich kann auf die gewünschte NSPredicate ein ähnliches Ergebnis erzielen mit:

NSMutableArray *filteredSet = [[NSMutableArray alloc] initWithCapacity:[data count]]; 
NSString *keySearch1 = [NSString stringWithString:@"bill"]; 
NSString *keySearch2 = [NSString stringWithString:@"joe"]; 

for (NSDictionary *currentDict in data){ 
    // objectForKey will return nil if a key doesn't exists. 
    if ([currentDict objectForKey:keySearch1] && [currentDict objectForKey:keySearch2]){ 
     [filteredSet addObject:currentDict]; 
    } 
} 

NSLog(@"filteredSet: %@", filteredSet); 

Ich stelle mir vor, NSPredicate wäre elegant, wenn ein solches vorhanden ist?

Antwort

24

sie nur Art und Weise, die ich kenne zwei Bedingungen zu kombinieren, wie „‚value1‘IN-Liste und‚value2‘IN-Liste“

selbst. @ AllKeys sollten alle Schlüssel des Wörterbuchs zurückzukehren (Selbst ist jedes Wörterbuch in Ihr Array). Wenn Sie nicht mit dem Präfix @ schreiben, dann wird das Wörterbuch suchen gerade nach einem Schlüssel, der „AllKeys“ anstelle des Verfahrens ist „- (NSArray *) AllKeys“

Der Code:

NSArray* billAndJoe = [data filteredArrayUsingPredicate:[NSPredicate predicateWithFormat:@"%@ IN [email protected] AND %@ IN [email protected]" , @"bill",@"joe" ]]; 


NSArray* joeAndJenny = [data filteredArrayUsingPredicate:[NSPredicate predicateWithFormat:@"%@ IN [email protected] AND %@ IN [email protected]" , @"joe",@"jenny" ]] 
+0

Er könnte auch NSCompoundPredicate '+ andPredicateWithSubpredicates:' verwenden, anstatt nur zwei Optionen fest zu codieren. –

+0

Danke. Ich werde es am Morgen versuchen. Der Code sieht aber wie ich aus! –

+0

Ok .. endlich wieder darauf zurück. Der Code funktioniert, müssen nur sicherstellen, dass es init-ed ist: 'NSArray * billAndJoe = [[NSArray alloc] InitWithArray: [NSArray ArrayWithArray: [Daten gefiltertArrayUsingPredicate: [NSPredicate Prädikat WithFormat: @"% @ IN selbst. @ AllKeys AND% @ IN selbst. @ AllKeys ", @" bill ", @" joe "]]]];' –

5

Da ein Wörterbuch nur nil zurückgibt, wenn Sie nach einem Wert eines nicht vorhandenen Schlüssels fragen, reicht es aus, anzugeben, dass der Wert nicht-null sein soll. Ein Format wie die folgenden soll Ihren ersten Fall abdecken:

[NSPredicate predicateWithFormat: @"%K != nil AND %K != nil", @"bill", @"joe"] 

Der zweite Fall mit „Joe“ und „jenny“ folgt ein ähnliches Muster, natürlich.