Быстрое перечисление для экземпляра NSDictionary, упорядоченного по ключу
обзор
- Я использую быстрое перечисление, чтобы перебрать экземпляр NSDictionary
- Я ожидал, что экземпляр NSDictionary будет перечислен в порядке возрастания ключа, но, похоже, это не так
Что я хочу сделать:
- Я хочу иметь возможность перебирать экземпляр NSDictionary в порядке возрастания ключа, используя быстрое перечисление
Примечание: пожалуйста, смотрите ожидаемый результат по сравнению с фактическим выходом
Вопросы
- Я делаю ошибку с моей реализацией?
- Гарантирует ли быстрое перечисление NSDictionary упорядочение по ключам?
- Если нет, то есть ли обходной путь для этого и все же использовать быстрое перечисление?
пример
#import<Foundation/Foundation.h>
int main()
{
system("clear");
NSDictionary *d1 = nil;
@autoreleasepool
{
d1 = [[NSDictionary alloc] initWithObjectsAndKeys: @"AAA", [NSNumber numberWithInt:10],
@"BBB", [NSNumber numberWithInt:20],
@"CCC", [NSNumber numberWithInt:30],
nil];
}
for(NSNumber* n1 in d1) //I expected fast enumeration for NSDictionary to be based on the
//ascending order of the key but that doesn't seem to be the case
{
printf("key = %p"
"\t [key intValue] = %i"
"\t value = %s\n",
n1,
[n1 intValue],
[[d1 objectForKey:n1] UTF8String]);
}
return(0);
}
Ожидаемый результат
key = 0xa83 [key intValue] = 10 value = AAA
key = 0x1483 [key intValue] = 20 value = BBB
key = 0x1e83 [key intValue] = 30 value = CCC
Фактический вывод
key = 0x1e83 [key intValue] = 30 value = CCC
key = 0xa83 [key intValue] = 10 value = AAA
key = 0x1483 [key intValue] = 20 value = BBB
3 ответа
Решение
- Нет, ваша реализация верна.
- Быстрое перечисление NSDictionary не гарантирует сортировку (и не будет выводить ничего по порядку из-за реализации в виде хешированного контейнера).
- Нет, ты должен разобраться сам.
for (NSString *key in [[d1 allKeys] sortedArrayUsingSelector:@selector(compare:)])
{
id value = [d1 valueForKey:key];
...
}
Нет никаких гарантий относительно порядка, в котором вы получите ваш объект.
AllKeys
Возвращает новый массив, содержащий ключи словаря.
- (NSArray *) allKeys
Возвращаемое значение
Новый массив, содержащий ключи словаря, или пустой массив, если в словаре нет записей.
обсуждение
Порядок элементов в массиве не определен.
Поэтому я предлагаю, если ваш словарь меняется не часто, кэшируйте NSArray
с ключом в том порядке, в котором вы хотите их.
Если ваш словарь часто меняется, возможно, вам придется отсортировать allKeys
когда они вам нужны.