2012-06-20 24 views
8

Considere el siguiente NSArray:NSPredicate 'O' de filtrado basado en una NSArray de llaves

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

soy capaz de filtrar esta matriz para encontrar objetos de diccionario que contienen la clavekey1

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

Cuál devuelve apropiadamente:

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

Ahora, deseo filtrar el conjunto de datos para objetos de diccionario que contienen CUALQUIER de las claves en un NSArray.

Por ejemplo, utilizando la matriz: NSArray *keySet = [NSArray arrayWithObjects:@"key1", @"key3", nil]; Quiero crear un predicado que devuelve y variedad de cualquier objetos diccionario que contengan bien 'key1' o 'key3' (es decir, en este ejemplo todos los objetos de diccionario haría. se devolverá a excepción del tercer objeto, ya que no contiene ni 'clave1' ni 'clave3').

¿Alguna idea sobre cómo conseguiría esto? ¿Tendría que usar un predicado compuesto?

Respuesta

9

El operador ANY de NSPredicate cubre lo siguiente:

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

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

El * any * era lo que me estaba perdiendo. No sé por qué creo que NSPredicate es tan difícil de entender. Gracias por tu respuesta. Monolo +1 :) –

+0

¿es sensible a mayúsculas y minúsculas? Eventualmente lo descubriré, pero espero que ya esté. Volveré a comentar más tarde. – coolcool1994

+0

@ coolcool1994 CUALQUIER e IN (y SELF) en el predicado anterior no distinguen entre mayúsculas y minúsculas (de hecho, a menudo los escribo en mayúsculas para que se destaquen), los nombres clave/método son, por lo tanto, '@ allKeys' _is_ distingue mayúsculas y minúsculas . – Monolo

1

hacer esto:

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

funciona perfectamente para mí. Esperanza útil

+0

Gracias por su contribución. Soy consciente de poder usar O. La razón por la que quería usar una matriz era para cualquier número de teclas en lugar de exactamente 2 teclas. –

1

Altough la pregunta ha sido contestada, también se podría usar bloques para mayor granularidad:

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

que podría ser reorganizado como usted querer, tal vez dentro de su propio método.

Cuestiones relacionadas