2012-06-20 19 views
8

Si consideri il seguente NSArray:NSPredicate 'O' di filtraggio sulla base di un NSArray di chiavi

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]; 

sono in grado di filtrare questo array per trovare gli oggetti del dizionario che contengono la chiavekey1

// 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); 

Che restituisce opportunamente:

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

Ora, voglio filtrare il set di dati per gli oggetti del dizionario contenenti ANY delle chiavi in ​​un NSArray.

Ad esempio, utilizzando l'array: NSArray *keySet = [NSArray arrayWithObjects:@"key1", @"key3", nil]; Voglio creare un predicato che restituisce e la matrice di eventuali oggetti dizionario che contengono 'key1' o 'key3' (cioè in questo esempio tutti gli oggetti del dizionario avrebbe fatto. essere restituito ad eccezione del terzo oggetto, poiché non contiene né "chiave1" o "chiave3").

Qualche idea su come raggiungere questo obiettivo? Dovrei usare un predicato composto?

risposta

9

La ANY gestore del NSPredicate copre questo:

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

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

Il * any * era quello che mi mancava. Non so perché trovo NSPredicate così difficile da capire. Grazie per la tua risposta. Monolo +1 :) –

+0

è sensibile alla distinzione tra maiuscole e minuscole? Alla fine lo scoprirò, ma spero che lo sia già. Ill commentare più tardi. – coolcool1994

+0

@ coolcool1994 ANY e IN (e SELF) nel predicato di cui sopra non fanno distinzione tra maiuscole e minuscole (infatti li scrivo spesso in maiuscolo per farli risaltare), i nomi chiave/metodo sono, quindi '@ allKeys' _is_ case sensitive . – Monolo

1

fare questo:

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); 

funziona perfettamente per me. Speranza Utile

+0

Grazie per l'input. Sono consapevole di poter usare OR. Il motivo per cui volevo utilizzare un array era per un numero qualsiasi di tasti anziché esattamente 2 tasti. –

1

Benche la questione è stata risolta, si potrebbe anche usare blocco per una maggiore granularità:

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]; 

che potrebbe essere riorganizzato come si voglio, forse con il suo metodo.

Problemi correlati