2013-07-31 30 views
12

Komunikuję się z interfejsem API, który odsyła NSDictionary jako odpowiedź z danymi, których potrzebuje moja aplikacja (dane są w zasadzie plikiem danych). Te dane są sortowane według najnowszych lub najstarszych, z najnowszymi elementami z przodu NSDictionary.Dzięki szybkiemu wyliczeniu i NSDictionary nie jest gwarantowane iterowanie w kolejności kluczy - jak mogę to zrobić, aby było w porządku?

Kiedy szybko wymieniam je za pomocą for (NSString *key in articles) { ... }, kolejność jest pozornie losowa, a więc kolejność na nich działa nie jest od najnowszej do najstarszej, tak jak chcę, ale zupełnie losowa zamiast tego.

Przeczytałem, a przy użyciu szybkiego wyliczenia z NSDictionary nie ma gwarancji iteracji w kolejności za pośrednictwem tablicy.

Jednak I potrzebuje do. Jak zrobić iterate przez NSDictionary w kolejności, w której znajduje się NSDictionary?

+0

Napisz własny słownik, a następnie. Jeśli CF/NSDictionary powie, że nie może zagwarantować zamówienia, to nie może zagwarantować zamówienia. Pisanie dobrego algorytmu sortowania może nie być takie trudne, ale jeśli potrzebujesz ich w kolejności wstawiania, może to być trudne, bez oznakowania obiektów. – CodaFi

+0

Czy masz jakieś dane wejściowe na temat interfejsu API? Wygląda na to, że powinien przesłać ci tablicę, a nie słownik. –

Odpowiedz

20

Jednym ze sposobów może być, aby uzyskać wszystkie klucze w zmienny tablicy:

NSMutableArray *allKeys = [[dictionary allKeys] mutableCopy]; 

A potem posortować tablicę do swoich potrzeb:

[allKeys sortUsingComparator: ....,]; //or another sorting method 

Następnie można iteracyjne nad tablicy (przy użyciu szybko wyliczenie tutaj zachowuje kolejność, jak sądzę) i uzyskać wartości słownika dla bieżącego klucza:

for (NSString *key in allKeys) { 
    id object = [dictionary objectForKey: key]; 
    //do your thing with the object 
} 
+0

Dlaczego 'mutableCopy'? Myślę, że lepiej po prostu użyć '[dictionary allKeys]'. – Jaybo

+2

Bo zaraz po tym tablica allkeys zostanie posortowana.Co jest możliwe tylko przez a) uczynienie z niego tablic zmiennych lub b) utworzenie kolejnej, posortowanej tablicy (jak w odpowiedzi rmaddys). Jest to wybór preferencji i wszystko jest tak dobre, jak inne. Ale miło komentować tę 2-letnią, zaakceptowaną odpowiedź;) – Mario

+0

Hy, sprawdź moją odpowiedź tutaj: http://stackoverflow.com/questions/32986/nsenumerator-performance-vs-for-loop-in-cocoa/30720339#30720339 –

9

Słowniki są z definicji nieuporządkowane. Jeśli chcesz zastosować zamówienie do kluczy, musisz posortować klucze.

NSArray *keys = [articles allKeys]; 
NSArray *sortedKeys = [keys sortedArrayUsingSelector:@selector(compare:)]; 
for (NSString *key in sortedKeys) { 
    // process key 
} 

Zaktualizuj sposób sortowania kluczy do swoich potrzeb.

3

Podobnie jak inne ludzie mówią, że nie możesz gwarantować porządku w NSDictionary. A czasami zamawianie własności allKeys nie jest tym, czego naprawdę chcesz. Jeśli naprawdę chcesz wyliczyć twój dyktat za pomocą porządku, w którym klucze zostały wstawione do twojego dyktanda, możesz utworzyć nową właściwość/zmienną NSMutableArray do przechowywania kluczy, aby zachować ich kolejność.

Everytime można wstawić nowy klucz w dict, włóż ją w swojej tablicy:

[articles addObject:someArticle forKey:@"article1"]; 
[self.keys addObject:@"article1"]; 

wyliczyć je w kolejności, po prostu zrobić:

for (NSString *key in self.keys) { 
    id object = articles[key]; 
} 
4

Można również bezpośrednio wyliczyć tak:

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

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



to jest wzięte z odpowiedzi dostarczone przez zneak w pytaniu: for each loop in objective c for accessing NSMutable dictionary

+0

Jak ta odpowiedź powinna zadziałać? 'xyz' jest pustą tablicą bez kluczy. – rmaddy