If you’ve ever needed to sort an NSDictionary by its keys, you’ll quickly discover that this functionality is missing from the NSDictionary class. This is because the order of keys in an NSDictionary is undefined (really, the concept has no meaning in an NSDictionary in the first place). So the basic process to follow is:
- Put the keys into an NSArray for ordering
- Sort the NSArray
- Traverse each key in the NSArray and obtain the -objectForKey
Here’s the code. (Note: this method uses its own bubble sort algorithm, but you could easily replace this with NSArray’s built-in sorting methods if you wanted to):
-(NSMutableArray*)bubbleSortDictionaryByKeys:(NSDictionary*)dict
{
//this method takes an NSDictionary and performs a basic bubblesort
//on its keys. It then returns those ordered keys as an NSMutableArray.
//You can then traverse the original NSDictionary and retrive its
//ordered objects by simply stepping through each key in the NSMutableArray.
if(!dict)
return nil;
NSMutableArray *sortedKeys = [NSMutableArray arrayWithArray: [dict allKeys]];
if([sortedKeys count] <= 0)
return nil;
else if([sortedKeys count] == 1)
return sortedKeys; //no sort needed
//perform bubble sort on keys:
int n = [sortedKeys count] -1;
int i;
BOOL swapped = YES;
NSString *key1,*key2;
NSComparisonResult result;
while(swapped)
{
swapped = NO;
for(i=0;i<n;i++)
{
key1 = [sortedKeys objectAtIndex: i];
key2 = [sortedKeys objectAtIndex: i+1];
//here is where we do our basic NSString comparison
//This can be easily customized.
//See the options for -compare: in NSString docs
result = [key1 compare: key2 options: NSCaseInsensitiveSearch];
if(result == NSOrderedDescending)
{
//we retain for good form, but these
//objects should still be safely
//retained by the dictionary:
[key1 retain];
[key2 retain];
//pop the two keys out of the array
[sortedKeys removeObjectAtIndex: i]; // key1
[sortedKeys removeObjectAtIndex: i]; // key2
//replace them
[sortedKeys insertObject: key1 atIndex: i];
[sortedKeys insertObject: key2 atIndex: i];
[key1 release];
[key2 release];
swapped = YES;
}
}
}
return sortedKeys;
}
And here’s an example of how it can be used:
NSDictionary *test = [NSDictionary dictionaryWithObjects:
[NSArray arrayWithObjects:
@"4",@"3",@"1",@"2",@"6",@"5",nil]
forKeys: [NSArray arrayWithObjects:
@"dog", @"cat", @"apple", @"big bear", @"zebra", @"porcupine", nil]];
NSMutableArray *keys = [self bubbleSortDictionaryByKeys: test];
NSEnumerator *arrayEnum = [keys objectEnumerator];
NSString *aKey = nil;
NSString *str = @"";
while((aKey = [arrayEnum nextObject]))
{
str = [str stringByAppendingString:
[NSString stringWithFormat:
@"\nKey: %@ -> %@", aKey, [test objectForKey: aKey]]];
}
NSLog(@"%@",str);
Output:
Key: apple -> 1
Key: big bear -> 2
Key: cat -> 3
Key: dog -> 4
Key: porcupine -> 5
Key: zebra -> 6