2013-07-31 14 views
12

Ich kommuniziere mit einer API, die ein NSDictionary als Antwort mit Daten zurücksendet, die meine App benötigt (die Daten sind im Grunde ein Feed). Diese Daten werden nach dem neuesten bis zum ältesten sortiert, mit den neuesten Elementen an der Vorderseite des NSDictionary.Mit schneller Enumeration und einem NSDictionary ist die Iteration in der Reihenfolge der Schlüssel nicht garantiert - wie kann ich es so machen, dass es in Ordnung ist?

Wenn ich schnell durch sie mit for (NSString *key in articles) { ... } nummeriere, ist die Reihenfolge anscheinend zufällig, und folglich ist die Reihenfolge, die ich auf ihnen betreibe, nicht in Reihenfolge vom neuesten zum ältesten, wie ich es will, aber völlig zufällig stattdessen.

Ich habe gelesen, und wenn schnelle Aufzählung mit NSDictionary verwendet wird, ist es nicht garantiert, um in der Reihenfolge durch das Array zu iterieren.

Allerdings brauche ich es zu. Wie führe ich es durch das NSDictionary in der Reihenfolge, in der NSDictionary ist?

+0

Schreiben Sie Ihr eigenes Wörterbuch, dann. Wenn CF/NSDictionary sagt, dass sie keine Bestellung garantieren können, können sie keine Bestellung garantieren. Es ist vielleicht gar nicht so schwer, einen guten Sortieralgorithmus zu schreiben, aber wenn Sie sie in der Reihenfolge des Einfügens benötigen, könnte das schwierig sein, ohne die Objekte irgendwie zu markieren. – CodaFi

+0

Haben Sie Eingaben in der API? Es hört sich so an, als würde es Ihnen ein Array schicken, kein Wörterbuch. –

Antwort

20

Eine Möglichkeit könnte sein, alle Schlüssel in einem änderbaren Array zu erhalten:

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

Und dann sortiert das Array auf Ihre Bedürfnisse:

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

Sie können dann über das Array iterieren (mit schnellen Aufzählung hier hält die Reihenfolge, denke ich), und erhalten Sie die Wörterbuch-Werte für die aktuelle Schlüssel:

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

Warum 'mutableCopy'? Ich denke, es ist besser, verwenden Sie einfach '[dictionary allKeys]'. – Jaybo

+2

Denn gleich danach wird das allKeys-Array sortiert.Dies ist nur möglich, indem a) ein veränderbares Array erstellt wird oder b) ein weiteres, sortiertes Array erstellt wird (wie in der Antwort von rmaddys). Es ist eine Präferenzwahl und alles ist so gut wie das andere. Aber schön, diese 2-jährige, akzeptierte Antwort zu kommentieren;) – Mario

+0

Hy, überprüfen Sie meine Antwort hier: http://stackoverflow.com/questions/32986/nsenumerator-performance-vs-for-loop-in-cocoa/30720339#30720339 –

9

Wörterbücher sind per Definition ungeordnet. Wenn Sie eine Bestellung auf die Schlüssel anwenden möchten, müssen Sie die Schlüssel sortieren.

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

Aktualisieren Sie die Art und Weise, wie die Schlüssel nach Ihren Bedürfnissen sortiert werden.

3

Als andere Leute sagten, Sie können Ordnung in NSDictionary nicht garantieren. Und manchmal, wenn Sie die allKeys-Eigenschaft bestellen, ist es nicht das, was Sie wirklich wollen. Wenn das, was Sie wirklich wollen, Ihr Diktat nach der Reihenfolge aufzählt, in der Ihre Schlüssel in Ihr Diktat eingefügt wurden, können Sie eine neue NSMutableArray-Eigenschaft/Variable zum Speichern Ihrer Schlüssel erstellen, so dass sie ihre Reihenfolge beibehalten.

Jedesmal, wenn man einen neuen Schlüssel in der dict einfügen, legen Sie sie in Ihrem Array:

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

Um sie in der Reihenfolge aufzählen, nur tun:

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

Sie können auch direkt aufzählen dies wie:

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

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



Dies ergibt sich aus der Antwort genommen zur Verfügung gestellt von Zneak in der Frage: for each loop in objective c for accessing NSMutable dictionary

+0

Wie soll diese Antwort funktionieren? 'xyz' ist ein leeres Array ohne Schlüssel. – rmaddy