2012-06-20 10 views
8

Betrachten Sie das folgende NSArray:NSPredicate 'OR' Filterung basierend auf einer NSArray von Schlüsseln

NSArray *dataSet = [[NSArray alloc] initWithObjects: 
       [NSDictionary dictionaryWithObjectsAndKeys:@"abc", @"key1", @"def", @"key2", @"hij", @"key3", nil], 
       [NSDictionary dictionaryWithObjectsAndKeys:@"klm", @"key1", @"nop", @"key2", nil], 
       [NSDictionary dictionaryWithObjectsAndKeys:@"qrs", @"key2", @"tuv", @"key4", nil], 
       [NSDictionary dictionaryWithObjectsAndKeys:@"wxy", @"key3", nil], 
       nil]; 

Ich bin in der Lage dieses Array filtern Wörterbuch Objekte zu finden, enthalten die Schlüsselkey1

// Filter our dataSet to only contain dictionary objects with a key of 'key1' 
NSString *key = @"key1"; 
NSPredicate *key1Predicate = [NSPredicate predicateWithFormat:@"%@ IN [email protected]", key]; 
NSArray *filteretSet1 = [dataSet filteredArrayUsingPredicate:key1Predicate]; 
NSLog(@"filteretSet1: %@",filteretSet1); 

Was in geeigneter Weise zurückkehrt:

filteretSet1: (
     { 
     key1 = abc; 
     key2 = def; 
     key3 = hij; 
    }, 
     { 
     key1 = klm; 
     key2 = nop; 
    } 
) 

Nun möchte ich das DataSet für Wörterbuchobjekte mit ANY der Schlüssel in einem NSArray filtern.

Zum Beispiel mit dem Array: NSArray *keySet = [NSArray arrayWithObjects:@"key1", @"key3", nil]; ich ein Prädikat erstellen möchten, und Array von gibt alle Dictionary-Objekte, die entweder ‚key1‘ oder ‚key3‘ enthalten (dh in diesem Beispiel alle Dictionary-Objekte würden. zurückgegeben werden, außer für das dritte Objekt - da es weder 'key1' noch 'key3' enthält.

Irgendwelche Ideen, wie ich das erreichen würde? Müsste ich ein zusammengesetztes Prädikat verwenden?

Antwort

9

Der ANY Betreiber von NSPredicate deckt dies:

NSArray *filter = [NSArray arrayWithObjects:@"key1", @"key3",nil]; 

NSPredicate *filterBlock = [NSPredicate predicateWithBlock: ^BOOL(id obj, NSDictionary *bind){   
    NSDictionary *data = (NSDictionary*)obj; 

    // use 'filter' and implement your logic and return YES or NO 
}]; 

[dataSet filteredArrayUsingPredicate:filterBlock]; 

dass, wie Sie neu geordnet werden:

NSSet *keys = [NSSet setWithObjects:@"key1", @"key3", nil]; 

NSPredicate *key1Predicate = [NSPredicate predicateWithFormat:@"any [email protected] in %@", keys]; 
+0

Das * an * war was ich vermisste. Ich weiß nicht, warum ich das NSPredicate so schwer finde. Danke für deine Antwort. Monolo +1 :) –

+0

ist dies Groß-und Kleinschreibung? Ich werde es irgendwann herausfinden, aber ich hoffe es ist schon. Ich werde später zurückkommen. – coolcool1994

+0

@ coolcool1994 ANY und IN (und SELF) im Prädikat oben sind nicht Groß-und Kleinschreibung (in der Tat schreibe ich sie oft in Großbuchstaben, um sie hervorzuheben), die Schlüssel/Methoden-Namen sind, so '@ allKeys' _is_ Groß-und Kleinschreibung . – Monolo

1

tun:

NSString *key = @"key1"; 
    NSString *key1 = @"key3"; 
    NSPredicate *key1Predicate = [NSPredicate predicateWithFormat:@"%@ IN [email protected] OR %@ IN [email protected]",key,key1]; 
    NSArray *filteretSet1 = [dataSet filteredArrayUsingPredicate:key1Predicate]; 
    NSLog(@"filteretSet1: %@",filteretSet1); 

Works für mich perfekt. Hoffe Hilfreiche

+0

Danke für Ihre Eingabe. Ich bin mir bewusst, dass ich OR verwenden kann. Der Grund, warum ich ein Array verwenden wollte, war eine beliebige Anzahl von Schlüsseln und nicht genau 2 Schlüssel. –

1

Altough die Frage beantwortet ist, können Sie auch Block für mehr Granularität verwenden könnte wollen, vielleicht in seiner eigenen Methode.