2011-05-31 14 views
21

Estoy intentando buscar objetos a partir de datos básicos que no están en un conjunto determinado, pero no he podido hacer que funcionen.obteniendo objetos de datos centrales que no están en un conjunto

Por ejemplo, supongamos que tenemos una entidad de datos central llamada Usuario, que tiene algunos atributos como userName, familyName, givenName y active. Dada una matriz de cadenas que representan un conjunto de nombres de usuario, podemos ir a buscar fácilmente todos los usuarios correspondientes a esa lista de nombres de usuario:

NSManagedObjectContext *moc = [[NSManagedObjectContext alloc] init]; 
NSFetchRequest *request = [[NSFetchRequest alloc] init]; 
NSEntityDescription *entity = [NSEntityDescription entityForName:@"User" 
              inManagedObjectContext:moc]; 
[request setEntity:entity]; 

NSArray *userNames = [NSArray arrayWithObjects:@"user1", @"user2", @"user3", nil]; 
NSPredicate *predicate = [NSPredicate predicateWithFormat:@"userName IN %@", userNames]; 
[request setPredicate:predicate]; 
NSArray *users = [moc executeFetchRequest:request error:nil]; 

Sin embargo, quiero ir a buscar el complemento de ese conjunto, es decir, quiero que todo el usuarios en datos centrales que no tienen los nombres de usuario especificados en la matriz userNames. ¿Alguien tiene una idea de cómo abordar este problema? Pensé que sería bastante simple agregar un "NOT" en el predicado (i.e., "userName NOT IN %@"), pero Xcode arroja una excepción diciendo que el formato de predicado no pudo ser analizado. También intenté usar el generador de predicados disponible para las solicitudes de recuperación sin suerte. La documentación tampoco fue particularmente útil. Sugerencias? ¿Comentarios? Gracias por toda su ayuda :)

Respuesta

52

el fin de encontrar los objetos que no están en la matriz, todo lo que tiene que hacer es algo como esto:

NSPredicate *predicate = [NSPredicate predicateWithFormat:@"NOT (userName IN %@)", userNames]; 

que debe devolver una solicitud de toda la objetos sin los que ha especificado

+0

Bastante simple ... Gracias, slev. – tomas

+0

fantástico. Pensé que no estaba funcionando. pero eso fue porque los datos en mi matriz eran de otro campo. Gracias. Simple y efectivo. –

+0

Nota: Esto no funciona con las variables NSNumber, que probablemente tenga sentido, pero es una pena si envuelve una enumeración en un NSNumber. En ese caso, use algo como '[NSPredicate predicateWithFormat: @" NOT (enumWrapper IN {% d,% d}) ", enum1, enum2]'. –

1

No soy fuerte en core data/objective-c pero el predicado debe ser como la siguiente declaración;

[predicateFormat appendFormat:@"not (some_field_name in {'A','B','B','C'})"]; 

Un ejemplo:

NSMutableString * mutableStr = [[NSMutableString alloc] init]; 

//prepare filter statement 
for (SomeEntity * e in self.someArray) { 
    [mutableStr appendFormat:@"'%@',", e.key]; 
} 

//excluded objects exist 
if (![mutableStr isEqual:@""]) 
{ 
    //remove last comma from mutable string 
    mutableStr = [[mutableStr substringToIndex:mutableStr.length-1] copy]; 

    [predicateFormat appendFormat:@"not (key in {%@})", mutableStr]; 
} 

//... 
//use this predicate in NSFetchRequest 
//fetchRequest.predicate = [NSPredicate predicateWithFormat:predicateFormat]; 
//... 
0

Aquí hay otro ejemplo útil, que muestra cómo tomar una lista de cadenas, y filtrar los que no comience con las letras AZ:

NSArray* listOfCompanies = [NSArray arrayWithObjects:@"123 Hello", @"-30'c in Norway", @"ABC Ltd", @"British Rail", @"Daily Mail" @"Zylophones Inc.", nil]; 

NSPredicate *bPredicate = [NSPredicate predicateWithFormat:@"NOT (SELF MATCHES[c] '^[A-Za-z].*')"]; 

NSArray *filteredList = [listOfCompanies filteredArrayUsingPredicate:bPredicate]; 

for (NSString* oneCompany in filteredList) 
    NSLog(@"%@", oneCompany); 

Utilizo este tipo de NSPredicate cuando estoy rellenando un UITableView con un índice AZ, y quiero una sección "todo lo demás" para los artículos que no comienzan con una letra.

Cuestiones relacionadas