para cada bucle en Objective-C para acceder al diccionario NSMutable


268

Me está resultando difícil acceder a claves y valores de diccionario mutables en Objective-C.

Supongamos que tengo esto:

NSMutableDictionary *xyz=[[NSMutableDictionary alloc] init];

Puedo establecer claves y valores. Ahora, solo quiero acceder a cada clave y valor, pero no sé la cantidad de claves configuradas.

En PHP es muy fácil, algo así:

foreach ($xyz as $key => $value)

¿Cómo es posible en Objective-C?

Respuestas:


662
for (NSString* key in xyz) {
    id value = xyz[key];
    // do stuff
}

Esto funciona para todas las clases que se ajustan al protocolo NSFastEnumeration (disponible en 10.5+ y iOS), aunque NSDictionaryes una de las pocas colecciones que le permite enumerar claves en lugar de valores. Le sugiero que lea sobre la enumeración rápida en el Tema de programación de colecciones .

Sin embargo, debo agregar que NUNCA debes modificar una colección mientras la enumeras.


44
Me preguntaba, ¿no debería haber sido: for (NSString * key in [xyz allKeys]) ?? O realmente no importa.
FlowUI. SimpleUITesting.com

66
@ user76859403 Enumerar un diccionario, de hecho, enumera las claves. for (NSString* key in [xyz allKeys])es conceptualmente lo mismo.
zneak

Use [xyz allKeys] si necesita mutar el diccionario mientras enumera las claves. Vea mi respuesta a continuación.
Brody Robertson

¿Este bucle devuelve el mismo orden todo el tiempo? ¿O necesitamos otra forma de usarlo para las secciones de TableView?
ymutlu

1
@ymutlu, los diccionarios de cacao no están ordenados. Esto significa que el orden en que iteran puede cambiar cada vez que los modifique.
zneak

98

Solo para no dejar de lado la opción 10.6+ para enumerar claves y valores usando bloques ...

[dict enumerateKeysAndObjectsUsingBlock:^(id key, id object, BOOL *stop) {
    NSLog(@"%@ = %@", key, object);
}];

Si desea que las acciones sucedan simultáneamente:

[dict enumerateKeysAndObjectsWithOptions:NSEnumerationConcurrent
                              usingBlock:^(id key, id object, BOOL *stop) {
    NSLog(@"%@ = %@", key, object);
}];

2
3 formas diferentes de enumerar a través de un diccionario. . . je, esto me recuerda la respuesta "Strangest Language Feature" donde VB tiene 7 tipos diferentes de bucles.
dreamlax

3
Bueno ... objectEnumerator se agregó en 1994, for for (... in ...) aproximadamente en 2006, y Blocks se agregaron en 2009. La forma de enumeración en bloque es una consecuencia natural.
bbum

Esto parece ser más rápido que el estándar para ... en construcción: oneofthesedaysblog.com/block-vs-for-in-objective-c-enumeration
lkraider

1
@lkraider, comenté en esa publicación, que en realidad compara la enumeración basada en bloques con un antiguo bucle for, no el for ... en construcción.
Quinn Taylor el

¿Para qué sirve *stop? ¿Cómo lo usas? Alguna referencia?
borisdiakur

13

Si necesita mutar el diccionario mientras enumera:

for (NSString* key in xyz.allKeys) {
    [xyz setValue:[NSNumber numberWithBool:YES] forKey:key];
}

El motivo es allKeysdevuelve una copia de las claves. Por lo tanto, es seguro mutar el diccionario.
Honghao Zhang

5

La forma más fácil de enumerar un diccionario es

for (NSString *key in tDictionary.keyEnumerator) 
{
    //do something here;
}

¿Dónde tDictionaryestá el NSDictionaryo NSMutableDictionaryquieres iterar?



2

La enumeración rápida se agregó en 10.5 y en el sistema operativo iPhone, y es significativamente más rápido, no solo el azúcar sintáctico. Si tiene que apuntar al tiempo de ejecución anterior (es decir, 10.4 y hacia atrás), deberá usar el método anterior de enumeración:

NSDictionary *myDict = ... some keys and values ...
NSEnumerator *keyEnum = [myDict keyEnumerator];
id key;

while ((key = [keyEnum nextObject]))
{
    id value = [myDict objectForKey:key];
    ... do work with "value" ...
}

No libera el objeto enumerador y no puede restablecerlo. Si desea comenzar de nuevo, debe solicitar un nuevo objeto enumerador del diccionario.


1

Puede usar -[NSDictionary allKeys]para acceder a todas las teclas y recorrerlas.


2
Es cierto, pero esto crea una matriz adicional autorrelegada, que puede ser bastante derrochadora, especialmente para diccionarios con muchas claves.
Quinn Taylor
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.