Current location: Brighton, UK

Sorting numerical NSStrings by playing with C

Posted on Tuesday, August 03, 2010 @ 14:32 CET

The other day I was trying to sort a list of value objects by their ID. I know, not very exciting, but easy enough right? Except these are numbers that are typed as NSStrings. So basically the object looks something like this:

@interface MyObject : NSObject {
NSString *objectId;
// Other properties would be defined here
}

I tried various things, such as sorting the list using a NSSortDescriptor like so:

NSSortDescriptor *descriptor = [[NSSortDescriptor alloc] initWithKey:@"objectId" ascending:YES];
NSArray *orderedList = [list sortedArrayUsingDescriptors:[NSArray arrayWithObject:descriptor]];
[descriptor release];

However that ordered the 12 items as 1, 11, 12, 2, 3, 4, 5, 6, 7, 8, 9. Not quite what I wanted. After some digging I found a lovely function that would do this, like so:

NSArray *orderedList = [list sortedArrayUsingFunction:compareObjectsUsingNumericalStringId context:@"objectId"];

The C function is quite straightforward:

static int compareObjectsUsingNumericalStringId(id p1, id p2, void *context) {
// Create a selector for the object's property
SEL methodSelector = NSSelectorFromString(context);
// Get the value
id obj1 = objc_msgSend(p1, methodSelector);
id obj2 = objc_msgSend(p2, methodSelector);
// We know objX is an NSString so get the int value for comparing
int v1 = [obj1 intValue];
int v2 = [obj2 intValue];
// Do the comparison
if (v1 < v2) {
return NSOrderedAscending;
}
else if (v1 > v2) {
return NSOrderedDescending;
}
else {
return NSOrderedSame;
}
}

And now the ordered items are 1, 2, 3, 4, etc as we would expect. One of those things that I'm sure I'll find useful in the future so better to leave it here where I can find it :) You can download an Xcode project here that shows this example in action.

- paulo

Post a comment:

You must have Flash and JavaScript enabled to post a comment.