dla każdej pętli w Objective-C w celu uzyskania dostępu do słownika NSMutable

268

Mam trudności w dostępie do zmiennych kluczy i wartości słownika w Objective-C.

Załóżmy, że mam to:

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

Mogę ustawić klucze i wartości. Teraz chcę tylko uzyskać dostęp do każdego klucza i wartości, ale nie znam liczby ustawionych kluczy.

W PHP jest to bardzo proste, coś takiego:

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

Jak to możliwe w Objective-C?

Sagar R. Kothari
źródło

Odpowiedzi:

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

Działa to dla każdej klasy zgodnej z protokołem NSFastEnumeration (dostępnym w wersji 10.5+ i iOS), chociaż NSDictionaryjest to jedna z niewielu kolekcji, która pozwala wyliczyć klucze zamiast wartości. Proponuję przeczytać o szybkim wyliczaniu w temacie Programowanie kolekcji .

Och, powinienem jednak dodać, że NIGDY nie należy modyfikować kolekcji podczas jej wyliczania.

skradać się
źródło
4
Zastanawiałem się, czy nie powinno być: for (klawisz NSString * w [xyz allKeys])? Czy to naprawdę nie ma znaczenia.
FlowUI. SimpleUITesting.com
6
@ user76859403 Wyliczanie słownika w rzeczywistości wylicza klucze. for (NSString* key in [xyz allKeys])jest koncepcyjnie tym samym.
zneak
Użyj [xyz allKeys], jeśli musisz mutować słownik podczas wyliczania kluczy. Zobacz moją odpowiedź poniżej.
Brody Robertson,
Czy ta pętla zwraca cały czas to samo zamówienie? A może potrzebujemy innego sposobu wykorzystania go w sekcjach TableView?
ymutlu
1
@ymutlu, słowniki kakao są nieuporządkowane. Oznacza to, że kolejność ich iteracji może ulec zmianie po każdej modyfikacji.
zneak
98

Aby nie pominąć opcji 10.6+ do wyliczania kluczy i wartości za pomocą bloków ...

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

Jeśli chcesz, aby działania były wykonywane jednocześnie:

[dict enumerateKeysAndObjectsWithOptions:NSEnumerationConcurrent
                              usingBlock:^(id key, id object, BOOL *stop) {
    NSLog(@"%@ = %@", key, object);
}];
Quinn Taylor
źródło
2
3 różne sposoby wyliczania za pomocą słownika. . . heh, przypomina mi to odpowiedź „Najdziwniejsza cecha językowa”, w której VB ma 7 różnych rodzajów pętli.
dreamlax
3
Cóż ... ObjectEnumerator został dodany w 1994 r., For (... w ...) około 2006 r., A bloki zostały dodane w 2009 r. Blokowa forma wyliczenia jest naturalnym opadem.
bbum
Wydaje się, że jest to szybsze niż standardowe dla ... w konstrukcji: oneofthesedaysblog.com/block-vs-for-in-objective-c-enumeration
lkraider
1
@lkraider, skomentowałem ten post, który faktycznie porównuje wyliczanie oparte na blokach ze starą pętlą for, a nie for w konstrukcji.
Quinn Taylor,
Do czego służy *stop? Jak z tego korzystasz? Jakieś referencje?
borisdiakur
13

Jeśli musisz mutować słownik podczas wyliczania:

for (NSString* key in xyz.allKeys) {
    [xyz setValue:[NSNumber numberWithBool:YES] forKey:key];
}
Brody Robertson
źródło
Powodem jest allKeyszwrócenie kopii kluczy. Dlatego mutowanie słownika jest bezpieczne.
Honghao Zhang
5

Najłatwiejszym sposobem wyliczenia słownika jest

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

gdzie tDictionaryjest NSDictionarylub NSMutableDictionarychcesz iterować.

Avinash
źródło
2

Szybkie wyliczanie zostało dodane w wersji 10.5 i iPhone OS i jest znacznie szybsze, nie tylko cukier syntaktyczny. Jeśli musisz celować w starsze środowisko wykonawcze (tj. 10.4 i wstecz), musisz użyć starej metody wyliczania:

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" ...
}

Nie zwalniasz obiektu wyliczającego i nie możesz go zresetować. Jeśli chcesz zacząć od nowa, musisz poprosić o nowy obiekt modułu wyliczającego ze słownika.

dreamlax
źródło
1

Możesz użyć, -[NSDictionary allKeys]aby uzyskać dostęp do wszystkich kluczy i przejść przez nie.

gcamp
źródło
2
To prawda, ale tworzy to dodatkową automatycznie wydawaną tablicę, co może być dość marnotrawstwem, szczególnie w przypadku słowników z dużą ilością kluczy.
Quinn Taylor