Czy istnieje sposób na iterację słownika?

Znam NSDictionaries jako coś, gdzie potrzebujesz key, Aby uzyskać value. Ale jak Mogę iterację nad wszystkimi keys i values w NSDictionary, abym wiedział, jakie są klucze i jakie są wartości? Wiem, że istnieje coś, co nazywa się for-in-loop in JavaScript. Czy jest coś podobnego w Objective-C?

Author: Alex Cio, 2009-08-16

3 answers

Tak, NSDictionary obsługuje szybkie wyliczanie. W Objective-C 2.0 możesz to zrobić:

// To print out all key-value pairs in the NSDictionary myDict
for(id key in myDict)
    NSLog(@"key=%@ value=%@", key, [myDict objectForKey:key]);

Alternatywną metodą (którą musisz użyć, jeśli używasz Mac OS X pre-10.5, ale nadal możesz używać na 10.5 i iPhonie) jest użycie 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]);
 297
Author: Adam Rosenfield,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-08-16 15:27:08

Podejście blokowe unika uruchamiania algorytmu wyszukiwania dla każdego klucza :

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

Even though NSDictionary jest zaimplementowany jako hashtable (co oznacza, że koszt wyszukania elementu jest O(1)), seokupy nadal spowalniają iterację o stały współczynnik.

Moje pomiary pokazują, że dla słownika d liczb ...

NSMutableDictionary* dict = [NSMutableDictionary dictionary];
for (int i = 0; i < 5000000; ++i) {
  NSNumber* value = @(i);
  dict[value.stringValue] = value;
}

... sumowanie liczb z podejściem blokowym ...

__block int sum = 0;
[dict enumerateKeysAndObjectsUsingBlock:^(NSString* key, NSNumber* value, BOOL* stop) {
  sum += value.intValue;
}];

... zamiast pętli ...

int sum = 0;
for (NSString* key in dict)
  sum += [dict[key] intValue];

... jest o 40% szybszy.

EDIT : nowe SDK (6.1+) wydaje się optymalizować iterację pętli, więc podejście pętli jest teraz o około 20% szybsze niż podejście blokowe , przynajmniej dla prostego przypadku powyżej.

 141
Author: Rok Strniša,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-05-12 20:38:35

Jest to iteracja przy użyciu podejścia blokowego:

    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.
    }];

Z autocompletion jest bardzo szybki do Ustawienia, i nie musisz się martwić o pisanie koperty iteracji.

 8
Author: Javier Calatrava Llavería,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-04-28 06:41:49