Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Sorting a NSArray

I have a NSArray of objects. Those objects have an int attribute called "distance". I would like to sort my array by distance.

Could someone please tell me how to do that ? I can't understand how the sortUsingSelector or sortUsingDescriptor methods are working...

Thanks

like image 592
Yoot Avatar asked Nov 28 '22 10:11

Yoot


1 Answers

I assume you're using an NSMutableArray, because an NSArray is immutable.

When you sort something, you want the end result to be arranged as

x1 <= x2 <= x3 <= x4 <= ... <= xN

How to define this <=? There are 3 solutions in ObjC.


1. -sortUsingSelector:

[arr sortUsingSelector:@selector(foo:)] means that its elements will be compared as*

x <= y      is equivalent to      [x foo:y] <= 0

For example, to sort a list of strings case-insensitively, you use [arr sortUsingSelector:@selector(caseInsensitiveCompare:)].


2. -sortUsingFunction:context:

This is similar to -sortUsingSelector:, but it uses a function pointer as input. [arr sortUsingFunction:funcptr context:ctx] means that its elements will be compared as

x <= y      is equivalent to      funcptr(x, y, ctx) <= 0

3. -sortUsingDescriptors:

This is the most complicated one. It takes a list of NSSortDescriptors which describe the expected order of the properties. One basic example:

NSSortDescriptor* desc = [[NSSortDescriptor alloc] initWithKey:@"distance" ascending:YES];
[arr sortUsingDescriptors:[NSArray arrayWithObject:desc]];
[desc release];

the descriptor tells the sort routine to "sort by the key distance in ascending order".

Suppose there are 2 keys, integers x ascending then and strings y descending, then you may write

NSSortDescriptor* dx = [[NSSortDescriptor alloc] initWithKey:@"x" ascending:YES];
NSSortDescriptor* dy = [[NSSortDescriptor alloc] initWithKey:@"y" ascending:NO selector:@selector(caseInsensitiveCompare:)];
[arr sortUsingDescriptors:[NSArray arrayWithObjects:x, y, nil]];
[dx release];
[dy release];

and so on.


Note: * Actually you should only return -1, 0 or 1.

like image 90
kennytm Avatar answered Jun 19 '23 10:06

kennytm