247

Tengo dificultades para acceder a las claves y valores del diccionario mutable en Objective-C.para cada bucle en el objetivo c para acceder al diccionario NSMutable

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 teclas configuradas.

En PHP es muy fácil, algo de la siguiente manera:

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

¿Cómo es posible en Objective-C?

Respuesta

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

Esto funciona para todas las clases que cumpla con el protocolo NSFastEnumeration (disponible en iOS y 10.5 +), aunque NSDictionary es una de las pocas colecciones que le permite enumerar las teclas en lugar de valores. Le sugiero que lea sobre fast enumeration en el Collections Programming Topic.

Oh, debo agregar sin embargo que debe NUNCA modificar una colección al enumerar a través de ella.

+3

Me estaba preguntando, no debería haber sido: para (clave NSString * en [xyz allKeys]) ?? ¿O realmente no importa? –

+5

@ user76859403 Enumerando un diccionario, de hecho, enumera las claves.'for (clave NSString * en [xyz allKeys])' es conceptualmente la misma cosa. – zneak

+0

Utilice [xyz allKeys] si necesita mutar el diccionario mientras enumera las claves. Ver mi respuesta a continuación. –

1

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

+2

Cierto, pero esto crea una matriz autorellenada extra, lo que puede ser bastante inútil, especialmente para diccionarios con muchas claves. –

2

La enumeración rápida se agregó en 10.5 y en el sistema operativo del iPhone, y es significativamente más rápida, no solo azúcar sintáctica. Si usted tiene que apuntar el tiempo de ejecución de más edad (es decir, 10.4 y al revés), que tendrá que utilizar el viejo método de la 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 se puede restablecerla . Si desea comenzar de nuevo, debe solicitar un nuevo objeto enumerador del diccionario.

94

Sólo para no dejar de lado la opción 10.6+ para enumerar las claves y valores utilizando bloques ...

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

si desea que los actos que ocurran 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. . . heh, esto me recuerda la respuesta de "Característica del lenguaje más extraño" donde VB tiene 7 tipos diferentes de bucles. – dreamlax

+3

Bueno ... objectEnumerator se agregó en 1994, el de (... en ...) alrededor de 2006, y los bloques se agregaron en 2009. La forma de enumeración en bloque es la precipitación natural. – bbum

+0

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

10

Si necesita mutar el diccionario al enumerar:

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

La razón es 'allKeys' devuelve una copia de claves. Por lo tanto, es seguro mutar el diccionario. –

3

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

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

donde tDictionary es el NSDictionary o NSMutableDictionary desea repetir.

Cuestiones relacionadas