Lots of times people ask about how to sort arrays of objects. Here is a brief tutorial on how to go about it
The NSMutableArray class supports quite a few different ways of sorting an array. The tools are quite powerful, and actually pretty easy to use once you get the hang of it.
Here is a brief description of most of them:
- sortUsingFunction uses a C function pointer.
- sortUsingDescriptors takes an array of NSSortDescriptor objects. This option lets you sort a list using multiple keys (by last name, and by first name within last name, or sales transactions by sale-person's name, and then by date of transaction within a sales person. )
- sortUsingComparator sorts an array using a new iOS 4 NSComparator block.
- sortUsingSelector works if you are sorting an array of objects that have a comparison method. (like NSStrings or NSArrays.)
If you're just sorting an array of NSNumbers, you can sort them with 1 call:
[arrayToSort sortUsingSelector:
@selector(compare:)];
That works because the objects in the array (NSNumber objects) implement the compare method. You could do the same thing for NSString objects, or even for an array of custom data objects that implement a compare method.
Here's some example code using comparator blocks. It sorts an array of dictionaries where each dictionary includes a number in a key "sort_key".
#define SORT_KEY @\"sort_key\"
[anArray sortUsingComparator:
^(id obj1, id obj2)
{
NSInteger value1 = [[obj1 objectForKey: SORT_KEY] intValue];
NSInteger value2 = [[obj2 objectForKey: SORT_KEY] intValue];
if (value1 > value2)
{
return (NSComparisonResult)NSOrderedDescending;
}
if (value1 < value2)
{
return (NSComparisonResult)NSOrderedAscending;
}
return (NSComparisonResult)NSOrderedSame;
}];
The code above goes through the work of getting an integer value for each sort key and comparing them, as an illustration of how to do it. Since NSNumber objects implement a compare method, it could be rewritten much more simply:
#define SORT_KEY @\"sort_key\"
[anArray sortUsingComparator:
^(id obj1, id obj2)
{
NSNumber* key1 = [obj1 objectForKey: SORT_KEY];
NSNumber* key2 = [obj2 objectForKey: SORT_KEY];
return [key1 compare: key2];
}];
or the body of the comparator could even be distilled down to 1 line:
return [[obj1 objectForKey: SORT_KEY] compare: [obj2 objectForKey: SORT_KEY]];
I tend to prefer simple statements and lots of temporary variables because the code is easier to read, and easier to debug. The compiler optimizes away the temporary variables anyway, so there is no advantage to the all-in-one-line version.
For completeness, here is an example of sortUsingFunction:
[anArray sortUsingFunction: compareObjects context: NULL];
That code requires that you have a global sort function like the one below
#define SORT_KEY @\"sort_key\"
NSInteger compareObjects(id obj1, id obj2, void *context)
{
NSNumber* key1 = [obj1 objectForKey: SORT_KEY];
NSNumber* key2 = [obj2 objectForKey: SORT_KEY];
return [key1 compare: key2];
}
NSString includes a wide range of comparison methods that let you specify case sensitive or non case sensitive searching, comparing or ignoring diacritical marks, comparing string representations of numbers, etc. You can use those comparison methods as part of most of the sorting approaches outlined above.
Replies
I am trying to use an MSMutableArray withObjectsAndKeys but seem to be having a problem getting specific data from just one of my 11 cells to a specific outlet. Here's my post:
http://www.iphonedevsdk.com/forum/iphone-sdk-development/97140-objective-c-if-else-if-else-if-statement.html#post402445
If you have any advice, I'd be very thankful for your help!
- Spam
- Abuse
- Troll
0 • Off Topic Insightful Disagree Dislike Like AwesomeHelium HD - Only $0.99 on the iPad App Store!
Make sure to also check out my website at http://isaranjha.com!
- Spam
- Abuse
- Troll
0 • Off Topic Insightful Disagree Dislike Like Awesome