online apple iphone objective-c ipad nsarray

iphone - apple - Buscar en NSArray por valor de valor coincidente



itunes (8)

¿Por qué no usar predicados para hacer eso por ti ?:

// For number kind of values: NSPredicate *predicate = [NSPredicate predicateWithFormat:@"SELF = %@", value]; NSArray *results = [array_to_search filteredArrayUsingPredicate:predicate]; // For string kind of values: NSPredicate *predicate = [NSPredicate predicateWithFormat:@"SELF contains[cd] %@", value]; NSArray *results = [array_to_search filteredArrayUsingPredicate:predicate]; // For any object kind of value (yes, you can search objects also): NSPredicate *predicate = [NSPredicate predicateWithFormat:@"SELF MATCHES %@", value]; NSArray *results = [array_to_search filteredArrayUsingPredicate:predicate];

Tengo una NSArray de objects , que tiene una propiedad particular llamada name (tipo NSString).
Tengo un segundo NSArray de NSStrings que son names .

Me gustaría obtener una NSArray de todos los objects cuya propiedad .name coincida con uno de los names en la segunda NSArray.

¿Cómo puedo hacer esto, de manera rápida y eficiente, ya que esto se requerirá con bastante frecuencia?


Aquí hay una manera simple:

NSPredicate *predicate = [NSPredicate predicateWithFormat:@"name == %@", nameToFind]; [listOfItems filteredArrayUsingPredicate:predicate];


Con sus estructuras de datos actuales, solo puede hacerlo en tiempo O (n ^ 2) haciendo un bucle sobre la primera matriz una vez para cada miembro de la segunda matriz:

NSMutableArray * array = [NSMutableArray array]; for (NSString * name in names) { for (MyObject * object in objects) { if ([[myObject name] isEqualToString:name]) { [array addObject:object]; } } }

(Alterne según lo sugerido por Stefan: haga un bucle sobre la matriz de objetos y pregunte a la matriz de nombres si containsObject: Objeto containsObject: para el nombre de cada objeto).

Pero si esto realmente necesita ser más rápido (realmente depende del tamaño de los arreglos y de la frecuencia con la que lo haga), puede mejorar esto introduciendo un NSDictionary que asigna los names del primer conjunto a sus objetos. Luego, cada una de esas búsquedas es O (1) y el tiempo total es O (n). (Tendría que mantener este diccionario siempre sincronizado con la matriz de objetos, lo que no es difícil con los accesores razonables. Esta técnica también tiene la restricción de que el mismo name no puede aparecer en más de un objeto).

Una forma alternativa de obtener este resultado (y que no tiene esa última restricción) es usar un NSSet para su segunda colección y luego recorrer el conjunto de objetos que containsObject: llamadaObjeto containsObject: con cada uno en el conjunto de nombres. Si esta técnica es mejor depende de si sus dos colecciones son aproximadamente del mismo tamaño, o si una es mucho más grande que la otra.



Me gusta usar este método:

NSIndexSet *indexes = [_items indexesOfObjectsPassingTest:^BOOL(id obj, NSUInteger idx, BOOL *stop) { return ((MyObject *)obj).name isEqualToString:name]; }]; if (indexes.count != 0) { //extract your objects from the indexSet, and do what you like... }


NSMutableArray * foundNames = [NSMutableArray array]; for (MyObject * objectWithName in objectCollection) { if ([names containsObject:objectWithName.name]) { [foundNames objectWithName]; } }


NSMutableArray* solutions = [NSMutableArray array]; for (Object* object in objects){ for (NSString* name in names){ if ([object.name isEqualToString:name]){ [solutions addObject:object]; break; // If this doesnt work remove this } } }


int count=0; if (range.location!=NSNotFound) { [searchindex addObject:[NSString stringWithFormat:@"%d",count]]; }