Получение ключей NSDictionary, отсортированных по их соответствующим значениям
У меня есть NSMutableDictionary
с целыми значениями, и я хотел бы получить массив ключей, отсортированных по возрастанию по их соответствующим значениям. Например, с помощью этого словаря:
mutableDict = {
"A" = 2,
"B" = 4,
"C" = 3,
"D" = 1,
}
Я бы хотел получить массив ["D", "A", "C", "B"]
. Разумеется, мой настоящий словарь намного больше, чем просто четыре предмета.
Ответы
Ответ 1
Метод NSDictionary
keysSortedByValueUsingComparator:
должен сделать трюк.
Вам просто нужен метод, возвращающий NSComparisonResult
, который сравнивает значения объекта.
Ваш словарь
NSMutableDictionary * myDict;
И ваш массив
NSArray *myArray;
myArray = [myDict keysSortedByValueUsingComparator: ^(id obj1, id obj2) {
if ([obj1 integerValue] > [obj2 integerValue]) {
return (NSComparisonResult)NSOrderedDescending;
}
if ([obj1 integerValue] < [obj2 integerValue]) {
return (NSComparisonResult)NSOrderedAscending;
}
return (NSComparisonResult)NSOrderedSame;
}];
Просто используйте объекты NSNumber
вместо числовых констант.
Кстати, это взято из:
https://developer.apple.com/library/content/documentation/Cocoa/Conceptual/Collections/Articles/Dictionaries.html
Ответ 2
NSDictionary имеет этот аккуратный метод под названием allKeys
.
Если вы хотите, чтобы массив отсортировался, keysSortedByValueUsingComparator:
должен сделать трюк.
Решение Richard также работает, но делает некоторые дополнительные вызовы, которые вам не нужны:
// Assuming myDictionary was previously populated with NSNumber values.
NSArray *orderedKeys = [myDictionary keysSortedByValueUsingComparator:^NSComparisonResult(id obj1, id obj2){
return [obj1 compare:obj2];
}];
Ответ 3
Здесь решение:
NSDictionary *dictionary; // initialize dictionary
NSArray *sorted = [[dictionary allKeys] sortedArrayUsingComparator:^NSComparisonResult(id obj1, id obj2) {
return [[dictionary objectForKey:obj1] compare:[dictionary objectForKey:obj2]];
}];
Ответ 4
Простейшее решение:
[dictionary keysSortedByValueUsingSelector:@selector(compare:)]
Ответ 5
Здесь я сделал что-то вроде этого:
NSMutableArray * weekDays = [[NSMutableArray alloc] initWithObjects:@"Sunday",@"Monday",@"Tuesday",@"Wednesday",@"Thursday",@"Friday",@"Saturday", nil];
NSMutableDictionary *dict = [[NSMutableDictionary alloc] init];
NSMutableArray *dictArray = [[NSMutableArray alloc] init];
for(int i = 0; i < [weekDays count]; i++)
{
dict = [NSMutableDictionary dictionaryWithObjectsAndKeys:[NSNumber numberWithInt:i],@"WeekDay",[weekDays objectAtIndex:i],@"Name",nil];
[dictArray addObject:dict];
}
NSLog(@"Before Sorting : %@",dictArray);
@try
{
//for using NSSortDescriptor
NSSortDescriptor *sortDescriptor = [[NSSortDescriptor alloc] initWithKey:@"WeekDay" ascending:YES];
NSArray *descriptor = @[sortDescriptor];
NSArray *sortedArray = [dictArray sortedArrayUsingDescriptors:descriptor];
NSLog(@"After Sorting : %@",sortedArray);
//for using predicate
//here i want to sort the value against weekday but only for WeekDay<=5
int count=5;
NSPredicate *Predicate = [NSPredicate predicateWithFormat:@"WeekDay <=%d",count];
NSArray *results = [dictArray filteredArrayUsingPredicate:Predicate];
NSLog(@"After Sorting using predicate : %@",results);
}
@catch (NSException *exception)
{
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Sorting cant be done because of some error" message:[NSString stringWithFormat:@"%@",exception] delegate:self cancelButtonTitle:@"Ok" otherButtonTitles:nil];
[alert setTag:500];
[alert show];
[alert release];
}