2012-06-11 8 views
10

Ho il seguente NSArray contenente NSDictionary (s):Utilizzando NSPredicate al filtro in base più chiavi (NON valori per tasto)

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

Sono voler creare un NSArray filtrato che contiene solo gli oggetti in cui il NSDictionary corrisponde a più "chiavi" usando NSPredicate.

Ad esempio:

  • filtro la matrice per contenere solo gli oggetti NSDictionary con chiavi "fattura" e "Joe" [risultato desiderato: nuovo NSArray conterrebbe i primi due oggetti NSDictionary]
  • filtro la matrice per contenere solo gli oggetti NSDictionary con chiavi "Joe" e "jenny" [risultato desiderato: nuovo NSArray conterrebbe i ultimi due oggetti NSDictionary]

Qualcuno può spiegare il formato di NSPredicate per raggiungere questo obiettivo?

Edit: posso ottenere un risultato simile a NSPredicate desiderato utilizzando:

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

sto immaginando NSPredicate sarebbe più elegante se ne esiste uno?

risposta

24

loro unico modo che conosco è quello di combinare due condizioni come " 'value1' nella lista E 'valore2' nella lista"

sé. @ AllKeys dovrebbero restituire tutte le chiavi del dizionario (sé è ogni dizionario in il tuo array). Se non si scrive con il prefisso @ allora il dizionario sarà solo cercare una chiave che è "allKeys" al posto del metodo "- (NSArray *) allKeys"

Il codice:

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

Poteva anche usare NSCompoundPredicate '+ andPredicateWithSubpredicates:' invece di codificare solo 2 scelte. –

+0

Grazie. Ci proverò questa mattina. Il codice sembra però quello che voglio! –

+0

Ok .. finalmente tornato a questo. Il codice funziona, basta accertarsi che sia allocazione inizializzata: 'NSArray * billAndJoe = [[NSArray alloc] initWithArray: [NSArray arrayWithArray: [data filteredArrayUsingPredicate: [NSPredicate predicateWithFormat: @"% @ IN self. @ AllKeys AND% @ IN self. @ AllKeys ", @" bill ", @" joe "]]]];' –

5

Poiché un dizionario restituisce nil solo se si richiede un valore di una chiave non esistente, è sufficiente specificare che il valore deve essere non nullo. Un formato come il seguente dovrebbe coprire il primo caso:

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

Il secondo caso, con "Joe" e "jenny" segue un modello simile, naturalmente.

Problemi correlati