2011-06-18 12 views
19

Tengo dos matrices. Una es una matriz de nombres y la otra es una matriz compuesta de cadenas tituladas "Sí" o "No". La ruta de índice de cada nombre en la matriz "nombre" se corresponde con la misma ruta de índice en la matriz "Sí/No". Por ejemplo:Obtener el índice del objeto en la matriz para buscar el objeto correspondiente en otra matriz

Names Array | Yes/No Array 
Person 1 | Yes 
Person 2 | No 
Person 3 | Yes 

¿Cuál sería la forma más fácil de buscar el nombre de una persona (posiblemente obtener la ruta del índice de la misma) y comprobar si son "Sí" o "No" en el "Sí/No, ¿matriz?

Además, no estoy seguro de si "index path" es el término correcto para usar. Si no es así, me refiero al número que un objeto está en una matriz.

+0

¿Mantiene la matriz de nombres ordenada o no? –

+1

@Bavarious Sin clasificar, pero lo genera un servidor, por lo que no hay duplicados. PengOne respondió mi pregunta sin embargo. Estaba buscando el método indexOfObject. – Preston

Respuesta

31

NSArray tiene un método llamado indexOfObject que devolverá el índice más bajo cuyo valor de matriz correspondiente sea igual a un Objeto o NSNotFound si no se encuentra dicho objeto. Si su conjunto de nombres no está ordenado, utilícelo para obtener el índice que luego puede conectar a la matriz Sí/No. Es decir, algo como lo siguiente:

NSString *answer = nil; 
NSUInteger index = [namesArray indexOfObject:@"John Smith"]; 
if (index != NSNotFound) { 
    answer = [yesNoArray objectAtIndex:index]; 
} 
return answer; 

Debido Bavarious hace preguntas donde Asumo, aquí es una mejor manera cuando la matriz de nombres está ordenada alfabéticamente.

int index = [self findName:@"John Smith"]; 
NSString *answer = nil; 
if (index >= 0) { 
    answer = [yesNoArray objectAtIndex:index]; 
} 
return answer; 

donde la función findName es una simple búsqueda binaria:

-(int)findName:(NSString *)name { 
    int min, mid, max; 
    NSComparisonResult comparisonResult; 
    min = 0; 
    max = [namesArray count]-1; 
    while (min <= max) { 
     mid = min + (max-min)/2; 
     comparisonResult = [name compare:[namesArray objectAtIndex:mid]]; 
     if (comparisonResult == NSOrderedSame) { 
      return mid; 
     } else if (comparisonResult == NSOrderedDescending) { 
      min = mid+1; 
     } else { 
      max = mid-1; 
     } 
    } 
    return -1; 
} 
+1

Podría haber usado el método de búsqueda binaria de 'NSArray'. ;-) –

+0

@Bavarious: ¡Tiene uno! Me siento bastante tonto por perder eso. – PengOne

9

Tratando de mantener sincronizados dos matrices es sólo buscar problemas. Se puede hacer, por supuesto, pero cada vez que modifique una matriz, debe recordar hacer un cambio correspondiente a la otra. Hágase un favor y evite toda esa clase de errores repensando la forma en que está almacenando datos.

En este caso, tiene un par {persona, booleano}. Una opción es almacenar cada par como un diccionario, y luego mantener una matriz de esos diccionarios. Este sería un plan particularmente bueno si puede ampliar el número de datos más allá de los dos que tiene. Otra opción sería usar un diccionario donde las claves son nombres de personas y los valores son sus valores de sí/no. Esto hace que la respuesta a su pregunta muy simple:

NSString *yesOrNo = [personDictionary objectForKey:personName]; 

Volviendo a su pregunta original, en el que todavía tiene las dos matrices, la más fácil que hay que hacer es iterar sobre la matriz persona hasta que encuentre el persona que está buscando, obtener el índice de ese nombre, y luego mirar hacia arriba el valor correspondiente en los sí/no matriz:

for (person in peopleArray) { 
    if ([person isEqualToString:thePersonYoureLookingFor]) { 
     yesNoValue = [yesNoArray objectAtIndex:[peopleArray indexOfObject:person]; 
     break; 
    } 
} 

eso está bien si el número de personas en la lista no es demasiado grande . Si la lista puede ser grande, querrá mantener ordenada la matriz de persona para que pueda hacer una búsqueda binaria. El problema allí, sin embargo, es que está sí/no, la matriz está separada, por lo que ordenar el arrayArray mientras se mantiene la matriz de sí/no en el orden correcto se vuelve complicado.

+0

+1: Dependiendo de los requisitos, un diccionario/clase personalizada y una matriz ordenada + búsqueda binaria también es una buena solución. –

+0

Eso es lo que originalmente quería hacer, pero no pude encontrar la manera de obtener toda esa información de mi servidor. Lo que estoy haciendo ahora es solicitar la lista de nombres y hacer que el servidor implosione los nombres y luego explotarlos en una matriz en mi aplicación. Luego haciendo lo mismo para la matriz de sí/no. ¿Cuál sería una mejor manera de hacer eso? – Preston

+2

@Preston, incluso si comienza con dos matrices, es fácil crear un diccionario a partir de dos matrices: 'peopleDictionary = [NSDictionary dictionaryWithObjects: yesNoArray andKeys: peopleArray];'. No es mucho más difícil si desea una variedad de diccionarios: simplemente cree un bucle que construya un diccionario a partir de los elementos correspondientes de cada matriz y luego agregue ese diccionario a la matriz final. La clase personalizada a la que aludió Bavarious también es una buena opción, especialmente si hay alguna lógica relacionada con una persona. – Caleb

2

También puede utilizar debajo del código, pueda extraerse de su utilidad para usted,

NSSortDescriptor *_lastDescriptor = [[NSSortDescriptor alloc] initWithKey:@"" ascending:YES]; 
NSArray *_lastArray = [NSArray arrayWithObject:_lastDescriptor]; 


firstCharacterArray = (NSMutableArray *)[[nameIndexesDictionary allKeys]  
sortedArrayUsingDescriptors:_lastArray]; 
//firstCharacterArray = (NSMutableArray *)[[nameIndexesDictionary allKeys]      
sortedArrayUsingSelector:@selector(localizedCaseInsensitiveCompare:)]; 

for (NSString *eachlastIndex in firstCharacterArray) 
{ 
NSSortDescriptor *lastDescriptor = [[NSSortDescriptor alloc] initWithKey:@"" 
                   ascending:YES]; 
//selector:@selector(localizedCaseInsensitiveCompare:)] ; 
NSArray *descriptorslast = [NSArray arrayWithObject:lastDescriptor]; 
[[nameIndexesDictionary objectForKey:eachlastIndex]  
sortUsingDescriptors:descriptorslast]; 
[lastDescriptor release]; 
} 
0

Puede utilizar indexOfObject método para obtener el índice del elemento.

por ejemplo

esto le dará índice de su objeto

NSInteger index = [yourArray indexOfObject:objectName]; 

Para ver el elemento correspondiente de otra matriz

[anotherArray objectAtIndex:index]; 

Esto funcionó para mí. Espero que esto ayude.

Cuestiones relacionadas