Je connais les dictionnaires comme quelque chose où il faut une clé pour obtenir une valeur. Mais comment puis-je itérer sur toutes les clés et valeurs d'un dictionnaire, afin de savoir quelles clés et quelles valeurs il contient ? Je sais qu'il existe un élément appelé pour-en-boucle en JavaScript. Existe-t-il quelque chose de similaire en Objective-C ?
Réponses
Trop de publicités?Oui, NSDictionary
supporte l'énumération rapide. Avec Objective-C 2.0, vous pouvez le faire :
// To print out all key-value pairs in the NSDictionary myDict
for(id key in myDict)
NSLog(@"key=%@ value=%@", key, [myDict objectForKey:key]);
L'autre méthode (que vous devez utiliser si vous ciblez Mac OS X pré-10.5, mais que vous pouvez toujours utiliser sur 10.5 et iPhone) consiste à utiliser un fichier de type 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]);
L'approche par blocs évite d'exécuter l'algorithme de recherche pour chaque clé :
[dict enumerateKeysAndObjectsUsingBlock:^(id key, id value, BOOL* stop) {
NSLog(@"%@ => %@", key, value);
}];
Même si NSDictionary
est mis en œuvre comme un table de hachage (ce qui veut dire que le coût de recherche d'un élément est de O(1)
), les recherches ralentissent toujours votre itération en un facteur constant .
Mes mesures montrent que pour un dictionnaire d
de chiffres ...
NSMutableDictionary* dict = [NSMutableDictionary dictionary];
for (int i = 0; i < 5000000; ++i) {
NSNumber* value = @(i);
dict[value.stringValue] = value;
}
... en résumant les chiffres avec l'approche par blocs ...
__block int sum = 0;
[dict enumerateKeysAndObjectsUsingBlock:^(NSString* key, NSNumber* value, BOOL* stop) {
sum += value.intValue;
}];
... plutôt que l'approche en boucle ...
int sum = 0;
for (NSString* key in dict)
sum += [dict[key] intValue];
... est environ 40% plus rapide .
EDIT : Le nouveau SDK (6.1+) semble optimiser l'itération de boucle, donc l'approche en boucle est maintenant environ 20% plus rapide que l'approche en bloc du moins pour le cas simple ci-dessus.