2013-07-31 8 views
12

Я общаюсь с API, который отправляет NSDictionary в качестве ответа с данными, которые нужны моему приложению (данные в основном являются фидом). Эти данные сортируются по новейшим и самым старым, с новейшими элементами в начале NSDictionary.С быстрым перечислением и NSDictionary, итерация в порядке ключей не гарантируется - как я могу сделать так, чтобы она была в порядке?

Когда я быстро перечислил их с помощью for (NSString *key in articles) { ... }, порядок выглядит случайным, и, следовательно, порядок, который я им нахожу, не в порядке от самого нового до самого старого, как я хочу, но совершенно случайного.

Я прочитал, и при использовании быстрого перечисления с NSDictionary не гарантируется итерация по порядку через массив.

Однако I необходимо это к. Как сделать так, чтобы он перебирал NSDictionary в том порядке, в котором находится NSDictionary?

+0

Напишите свой собственный словарь. Если CF/NSDictionary говорят, что они не могут гарантировать порядок, то они не могут гарантировать порядок. Возможно, не так уж сложно написать хороший алгоритм сортировки, но если вам это нужно в порядке вставки, это может быть сложно, не помещая объекты каким-то образом. – CodaFi

+0

Есть ли у вас какие-либо данные по API? Похоже, он должен посылать вам массив, а не словарь. –

ответ

20

Одним из способов может быть, чтобы получить все ключи в изменяемый массив:

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

А затем отсортировать массив для ваших нужд:

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

Вы можете итерацию по массиву (с помощью быстрого перечисление здесь хранит порядок, я думаю) и получить значения словаря для текущего ключа:

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

Почему 'mutableCopy'? Я думаю, что лучше просто использовать '[dictionary allKeys]'. – Jaybo

+2

Поскольку сразу после этого массив allKeys сортируется.Это возможно только путем: a) создания изменяемого массива или b) создания еще одного, отсортированного массива (например, в ответе rmaddys). Это выбор предпочтений, и все так же хорошо, как и другое. Но приятно прокомментировать этот 2-летний старый принятый ответ;) – Mario

+0

Hy, проверьте мой ответ здесь: http://stackoverflow.com/questions/32986/nsenumerator-performance-vs-for-loop-in-cocoa/30720339#30720339 –

9

Словари по определению неупорядочены. Если вы хотите применить заказ к ключам, вам нужно отсортировать ключи.

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

Обновите способ сортировки ключей в соответствии с вашими потребностями.

3

Как и другие люди сказали, что вы не можете гарантировать порядок в NSDictionary. И иногда заказывая свойство allKeys, это не то, что вы действительно хотите. Если то, что вам действительно нужно, это перечислить ваш dict по порядку, в который ваши ключи были вставлены в ваш dict, вы можете создать новое свойство/переменную NSMutableArray для хранения ваших ключей, чтобы они сохранили свой заказ.

Everytime вы вставить новый ключ в Словаре, вставьте его в массиве:

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

Чтобы перечислить их в порядке, просто сделать:

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

Вы также можете непосредственно перечислить как это:

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

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



Это взято из ответа предоставленный zneak в вопрос: for each loop in objective c for accessing NSMutable dictionary

+0

Как должен отвечать этот ответ? 'xyz' - пустой массив без ключей. – rmaddy