быстрое перечисление для экземпляра NSDictionary, упорядоченного по ключу - PullRequest
4 голосов
/ 16 декабря 2011

Обзор

  • Я использую быстрое перечисление для итерации экземпляра NSDictionary
  • Я ожидал, что экземпляр NSDictionary будет перечисляться на основе возрастающего порядка ключа, но это не такКажется, дело обстоит так:

Что я хочу сделать:

  • Я хочу иметь возможность перебирать экземпляр NSDictionary в порядке возрастания ключа, используя быстрое перечисление

Примечание: Просьба просмотреть ожидаемый результат в сравнении с фактическим результатом

Вопросы

  1. Я ошибаюсь в своей реализации?
  2. Гарантирует ли быстрое перечисление NSDictionary упорядочение по ключам?
  3. Если нет, то есть ли обходной путь для этого и все же использовать быстрое перечисление?

Пример

#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 ]

13 голосов
/ 16 декабря 2011
for (NSString *key in [[d1 allKeys] sortedArrayUsingSelector:@selector(compare:)])
{
    id value = [d1 valueForKey:key];
    ...
}
2 голосов
/ 16 декабря 2011
  1. Нет, ваша реализация верна.
  2. Быстрое перечисление NSDictionary не гарантирует сортировку (и не будет выводить ничего по порядку из-за реализации в виде хешированного контейнера).
  3. Нет,Вы должны сортировать это самостоятельно.
1 голос
/ 16 декабря 2011

Нет никаких гарантий относительно порядка получения вашего объекта.

allKeys
Возвращает новый массив, содержащий ключи словаря.
- (NSArray *) allKeys
Возвращаемое значение
Новый массив, содержащий ключи словаря, или пустой массив, если в словаре нет записей.
Обсуждение
Порядок элементов в массиве не определен .

Поэтому я предлагаю, если ваш словарь меняется не часто, кешируйте NSArray с ключом в том порядке, в котором вы их хотите.
Если ваш словарь часто меняется, вы можетепридется сортировать allKeys, когда они вам нужны.

...