Getting NSDictionary keys sorted by their respective values
Solution 1
The NSDictionary
Method keysSortedByValueUsingComparator:
should do the trick.
You just need a method returning an NSComparisonResult
that compares the object's values.
Your Dictionary is
NSMutableDictionary * myDict;
And your Array is
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;
}];
Just use NSNumber
objects instead of numeric constants.
BTW, this is taken from: https://developer.apple.com/library/content/documentation/Cocoa/Conceptual/Collections/Articles/Dictionaries.html
Solution 2
Here's a solution:
NSDictionary *dictionary; // initialize dictionary
NSArray *sorted = [[dictionary allKeys] sortedArrayUsingComparator:^NSComparisonResult(id obj1, id obj2) {
return [[dictionary objectForKey:obj1] compare:[dictionary objectForKey:obj2]];
}];
Solution 3
The simplest solution:
[dictionary keysSortedByValueUsingSelector:@selector(compare:)]
Solution 4
Here i have done something like this:
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];
}
Eric
Updated on July 09, 2022Comments
-
Eric almost 2 years
I have an
NSMutableDictionary
with integer values, and I'd like to get an array of the keys, sorted ascending by their respective values. For example, with this dictionary:mutableDict = { "A" = 2, "B" = 4, "C" = 3, "D" = 1, }
I'd like to end up with the array
["D", "A", "C", "B"]
. My real dictionary is much larger than just four items, of course. -
Hermann Klecker about 12 yearsRichard's proposal is more elegant than mine because NSNumber already comes with a suitable compare function but mine is probably more general.
-
Richard J. Ross III about 12 yearsIn most cases, this solution will work fine, but what my answer has is the ability to support other types that respond to the
-compare:
-
ViruMax about 10 yearsworking correctly for strings starting with alphabates only, but when there is a string starting with number 10, its comming between first string starting with "A" and third string starting with "A"
-
nemesis over 9 yearsCheck the answer above, it's more intuitive and concise, even though this does the same thing.
-
Pradumna Patil almost 9 yearshow to write that compare function
-
onCompletion over 8 yearsPlease explain the compare method also.
-
Mr.G over 7 yearsThis will returns the key list , is there anyway that can get the dictionary directly , instead of having list of sorted keys in array
-
Hermann Klecker over 7 years@Mr.G, no there is no way as NSDictionary and NSMutableDictionare are not sorted. You cannot sort them and expect them to be sorted afterwards.
-
dgatwood over 7 yearsFor existing types (e.g. NSString), that method already exists. For anything you create yourself, the method should return NSOrderedAscending, NSOrderedSame, or NSOrderedDescending, depending on the order. See the documentation for
compare:options:range:
for more info.