Sé NSDictionaries
como algo donde necesita un key
para obtener un value
. Pero ¿cómo puedo iterar sobre keys
y values
en un NSDictionary
, para saber qué claves hay y qué valores hay? Sé que hay algo llamado for-in-loop en JavaScript
. ¿Hay algo similar en Objective-C
?¿Hay alguna manera de iterar sobre un diccionario?
Respuesta
Sí, NSDictionary
admite la enumeración rápida. Con Objective-C 2.0, usted puede hacer esto:
// To print out all key-value pairs in the NSDictionary myDict
for(id key in myDict)
NSLog(@"key=%@ value=%@", key, [myDict objectForKey:key]);
El método alternativo (que usted tiene que utilizar si se orienta a Mac OS X pre-10.5, pero todavía se puede utilizar en el 10,5 y el iPhone) es utilizar un NSEnumerator
:
NSEnumerator *enumerator = [myDict keyEnumerator];
id key;
// extra parens to suppress warning about using = instead of ==
while((key = [enumerator nextObject]))
NSLog(@"key=%@ value=%@", key, [myDict objectForKey:key]);
el enfoque de bloques de evita ejecutar el algoritmo de búsqueda para cada llave :
[dict enumerateKeysAndObjectsUsingBlock:^(id key, id value, BOOL* stop) {
NSLog(@"%@ => %@", key, value);
}];
Aunque NSDictionary
se implementa como hashtable (lo que significa que el costo de buscar un elemento es O(1)
), las búsquedas aún ralentizan su iteración por un factor constante.
Mis medidas muestran que para un diccionario de números d
...
NSMutableDictionary* dict = [NSMutableDictionary dictionary];
for (int i = 0; i < 5000000; ++i) {
NSNumber* value = @(i);
dict[value.stringValue] = value;
}
... resumiendo los números con el enfoque de bloques ...
__block int sum = 0;
[dict enumerateKeysAndObjectsUsingBlock:^(NSString* key, NSNumber* value, BOOL* stop) {
sum += value.intValue;
}];
... en lugar de el enfoque de bucle ...
int sum = 0;
for (NSString* key in dict)
sum += [dict[key] intValue];
... es ab fuera 40% más rápido.
EDITAR: El nuevo SDK (6.1 y posteriores) parece optimizar iteración del bucle, por lo el enfoque de bucle es ahora aproximadamente un 20% más rápido que el enfoque del bloque de, al menos para el caso simple anteriormente.
¿Qué hay de iOS 10/11, cuál es más rápido? – Supertecnoboff
elegante, ¡me encanta! – YvesLeBorg
Ésta es la iteración usando el enfoque de bloques:
NSDictionary *dict = @{@"key1":@1, @"key2":@2, @"key3":@3};
[dict enumerateKeysAndObjectsUsingBlock:^(id key, id obj, BOOL *stop) {
NSLog(@"%@->%@",key,obj);
// Set stop to YES when you wanted to break the iteration.
}];
Con la terminación automática es muy rápido para establecer, y usted no tiene que preocuparse de escribir sobre iteración.
Gracias .. Buena solución si necesita mutar el 'NSMutableDictionary' en el proceso – jose920405
- 1. Python iterar sobre un diccionario
- 2. Google Filtrar: iterar sobre un diccionario JSON
- 3. Iterar sobre el diccionario anidado
- 4. C# Iterar sobre Diccionario ordenado por valor
- 5. ¿Cómo iterar sobre un diccionario de Python, ordenado por valores?
- 6. ¿Hay alguna manera más pitónica de construir este diccionario?
- 7. ¿Iterar sobre los diccionarios VBA?
- 8. F # iteración sobre un diccionario
- 9. ¿Hay alguna manera fácil de iterar en un NSArray al revés?
- 10. Iterar a través de un diccionario VB6
- 11. ¿Hay alguna manera de iterar un número específico de veces sin introducir una variable innecesaria?
- 12. ¿Manera eficiente de iterar sobre bits verdaderos en std :: bitset?
- 13. ¿Hay alguna manera de negar un predicado?
- 14. ¿Hay alguna manera de romper un ciclo foreach en velocidad?
- 15. ¿Hay un diccionario sobre vocabulario común de programación?
- 16. Manera pitónica de iterar sobre una matriz 3D
- 17. perl: iterar sobre un typeglob
- 18. ¿Cómo iterar sobre un TreeMap?
- 19. Para un diccionario de Python, ¿iterkeys ofrece alguna ventaja sobre las teclas de acceso?
- 20. Python: iterar sobre la lista de artículos de diccionario vs sobre la eficiencia
- 21. ¿Hay alguna manera de inicializar un objeto mediante un hash?
- 22. Iterar sobre enum?
- 23. ¿Hay alguna manera más rápida de iterar a través de las filas de la consulta Sqlite?
- 24. Manera pitónica de iterar sobre los bits del número entero
- 25. ¿Hay alguna manera de obtener datos ortográficos de un NSString?
- 26. ¿Hay alguna manera de expandir un plegado de Vim automáticamente cuando colocas el cursor sobre él?
- 27. Macro para iterar sobre un GList
- 28. ¿Hay alguna manera de cambiar el propietario de un JDialog?
- 29. Python: Iterar listas con diferente cantidad de dimensiones, ¿hay alguna manera genérica?
- 30. ¿Cómo iterar sobre un hash en Ruby?
El enfoque de bloque es más rápido. Ver http://stackoverflow.com/a/12454766/974531. –
Sintaxis moderna ObjC: NSLog (@ "clave =% @ valor =% @", clave, myDict [clave]); – geowar
@Darthenius debido a las optimizaciones recientes, la enumeración rápida es de nuevo más rápida que la basada en bloques, al menos en ciertos casos. Pero si el problema que está resolviendo le permite usar la opción concurrente, el enfoque basado en bloques puede ser más rápido. –