2011-06-09 20 views
40

No estoy seguro de cómo hacerlo. Tengo un NSMutableArray (addList) que contiene todos los elementos que se agregarán a mi fuente de datos NSMutableArray.NSMutableArray compruebe si el objeto ya existe

Ahora quiero comprobar si el objeto que se va a agregar desde la matriz addList ya existe en la matriz del origen de datos. Si no existe, agregue el artículo, si existe, ignore.

Ambos objetos tienen una variable de cadena llamada iName que quiero comparar.

Aquí es mi fragmento de código

-(void)doneClicked{ 
    for (Item *item in addList){ 
     /* 
     Here i want to loop through the datasource array 
     */ 
     for(Item *existingItem in appDelegate.list){ 
      if([existingItem.iName isEqualToString:item.iName]){ 
       // Do not add 
      } 
      else{ 
       [appDelegate insertItem:item]; 
      } 
     } 
} 

pero encuentro el elemento que se añade incluso si existe.

¿Qué estoy haciendo mal?

+0

Es un error de lógica, véase mi respuesta – knuku

Respuesta

39

he encontrado una solución, no puede ser el más eficiente de todos, pero al menos funciona

NSMutableArray *add=[[NSMutableArray alloc]init]; 

for (Item *item in addList){ 
     if ([appDelegate.list containsObject:item]) 
      {} 
     else 
      [add addObject:item]; 
} 

Luego iterar sobre la matriz de agregar e insertar elementos.

5

¿Has probado indexOfObject:?

-(void)doneClicked{ 
    for (Item *item in addList){ 
     if([appDelegate.list indexOfObject:item] == NSNotFound){ 
      [appDelegate insertItem:item]; 
     } 
} 

ACTUALIZACIÓN: Usted tiene un error lógico, no hay que confundir en el código. supongamos que la primera matriz es ['a', 'b', 'c'], y la segunda es ['a', 'x', 'y', 'z']. Cuando iteras con 'a' a través de la segunda matriz, no agregará 'a' a la segunda matriz en la primera iteración (compara 'a' con 'a') pero agregará durante la segunda (compara 'a' con 'x '). Es por eso que debe implementar el método isEqual: (ver abajo) en su objeto 'Artículo' y usar el código anterior.

- (BOOL)isEqual:(id)anObject { 
    if ([anObject isKindOfClass:[Item class]]) 
     return ([self.iName isEqualToString:((Item *)anObject).iName]); 
    else 
     return NO; 
} 
+0

@ NR4TR: quiero comparar los nombres solos. No todo el objeto – Neelesh

+0

echa un vistazo a la respuesta actualizada – knuku

+0

Sí, lo consigo ahora. Pero cuando uso el código que ha actualizado, obtengo el siguiente error [Item isEqualToString:]: selector no reconocido enviado a la instancia 0x712ee70 – Neelesh

2

Puede anular isEquals y hash en el objeto para que devuelva un SI/NO en base a la comparación de la propiedad INAME.

Una vez que tenga que puede utilizar ...

- (void)removeObjectsInArray:(NSArray *)otherArray 

Para limpiar la lista antes de añadir todos los objetos restantes.

+0

en primer lugar, quiero comparar los nombres solo y no todo el objeto. – Neelesh

+1

considere leer la documentación acerca de 'método isEquals', podría ayudar a – knuku

+1

Sí, la idea de anular el isEquals es que luego se puede definir lo que se considera ' equal '. Normalmente el tiempo de ejecución mirará dos objetos y si no son la misma instancia devolverá falso. Al anular el método isEquals puede decir' en realidad no me importa si los OBJETOS no son lo mismo, en mi opinión, estos dos elementos son iguales si el nombre coincide. ' –

1

minúsculas Convierte y Recorte de espacio en blanco y luego verificar ..

[string lowercaseString]; 

y

NSString *trim = [string stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceCharacterSet]]; 
22

Uso NSPredicate.

NSArray *list = [[appDelegate.list copy] autorelease]; 

for (Item *item in addList) { 

    NSPredicate *predicate = [NSPredicate predicateWithFormat:@"iName MATCHES %@", item.iName]; 
    NSArray *filteredArray = [list filteredArrayUsingPredicate:predicate]; 
    if ([filteredArray count] > 0) [appDelegate insertItem:item]; 
} 
+1

+1 buena respuesta. También evita la excepción de colección mutante que sucedería si el método utilizado en la pregunta realmente funcionó. – JeremyP

+0

¿gestión de memoria para 'list' array? :) – knuku

+0

Probé la solución editada anterior. Primero, el programa se bloquea sin mostrar ningún error. En segundo lugar, el elemento se agrega incluso si existe en la lista de fuentes de datos – Neelesh

2

NR4TR dijo correctamente, pero creo que uno ruptura declaración es suficiente


if([existingItem.iName isEqualToString:item.iName]){ 
       // Do not add 
break; 
      } 
+0

puede pegar todo el código para el método. – Neelesh

4

Eche un vistazo a NSSet. Puede agregar objetos y el objeto solo se agregará si el objeto es único. Puede crear un NSSet desde un NSArray o viceversa.

68

Hay un método muy útil para esto en NSArray, es decir, contiene el objeto.

NSArray *array; 
array = [NSArray arrayWithObjects: @"Nicola", @"Margherita",          @"Luciano", @"Silvia", nil]; 
if ([array containsObject: @"Nicola"]) // YES 
{ 
    // Do something 
} 
1

Se trata de comparar primer objeto de la AddList y primer objeto de appDelegate.list, si no son iguales, se inserta el objeto de la AddList. La lógica es incorrecta, debe comparar un objeto de addList con cada objeto de appDelegate.list.

Cuestiones relacionadas