2012-06-26 3 views
7

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

например.

{ 
blue:12; 
red:50; 
white:44; 
} 

Я хотел бы они отсортированы по количеству спускающихся к:

{ 
red:50; 
white:44; 
blue:12 
} 

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

NSArray* sortedKeys = [stats keysSortedByValueUsingComparator:^(id first, id second) { 

    if (first < second) { 
     return (NSComparisonResult)NSOrderedAscending; 
    } else if (first > second) { 
     return (NSComparisonResult)NSOrderedDescending; 
    } else { 
     return (NSComparisonResult)NSOrderedSame; 
    } 

    }]; 

ответ

9

Концептуально NSDictionary является несортированным, как уже сказано C0deH4cker.

Если вам нужен заказ, вы можете либо написать ключи в массив (но у вас могут быть проблемы с сохранением массива после того, как ключ был удален из словаря, но есть учебники, как создать un-retaining array by using the CFArray) или NSSortedSet.

Или вы можете подкласс NSDictionary - не очень тривиально, поскольку NSDictionary - кластер классов. Но, к счастью, Мэтт показывает в своем фантастическом блоге "OrderedDictionary: Subclassing a Cocoa class cluster", как использовать небольшой трюк, покрытый имеет отношения.


Обратите внимание, что ваш код

NSArray* sortedKeys = [stats keysSortedByValueUsingComparator:^(id first, id second) { 

    if (first < second) { 
     return (NSComparisonResult)NSOrderedAscending; 
    } else if (first > second) { 
     return (NSComparisonResult)NSOrderedDescending; 
    } else { 
     return (NSComparisonResult)NSOrderedSame; 
    } 

    }]; 

обыкновение делать то, что вы хотите, чтобы это сделать, как вы подаете C-операторов к объектам. Теперь их указатели будут заказаны.

это должно быть что-то вроде

NSArray* sortedKeys = [stats keysSortedByValueUsingComparator:^(id first, id second) { 
    return [first compare:second]; 
    }]; 

или если вы хотите сделать заказ на скаляры, которые являются обертками в качестве объектов (т.е. NSNumber)

NSArray* sortedKeys = [stats keysSortedByValueUsingComparator:^(id first, id second) { 
    if ([first integerValue] > [second integerValue]) 
     return (NSComparisonResult)NSOrderedDescending; 

    if ([first integerValue] < [second integerValue]) 
     return (NSComparisonResult)NSOrderedAscending; 
    return (NSComparisonResult)NSOrderedSame; 
}]; 
0

Словари по определению неупорядочены. Доступ к ним осуществляется с использованием хэш-таблиц для скорости. Единственный способ, которым вы сможете «заказать» это выбрать другой тип данных. Тип данных bast зависит от ваших намерений.

+0

Я хотел бы преобразовать данные в упорядоченный nsarray в качестве вывода, но я начинаю с nsdictionary – MonkeyBonkey

0

Или вы можете просто сортировать ключи NSString напрямую например:

NSArray* sortedKeys = [sortedKeys sortedArrayUsingComparator:^NSComparisonResult(id _Nonnull obj1, id _Nonnull obj2) { 
     NSNumber *A = @([obj1 LongValue]); 
     NSNumber *B = @([obj2 LongValue]); 

     return [A compare:B]; 
    } ]; 
Смежные вопросы