2

I'm trying to sort an array passing an argument to the selector. For instance, I have an array of locations and I want to sort this array based on the distance they have from a certain point (for instance, my current location).

This is my selector, however I don't know how to call it.

- (NSComparisonResult)compareByDistance:(POI*)otherPoint withLocation:(CLLocation*)userLocation {
    int distance = [location distanceFromLocation:userLocation];
    int otherDistance = [otherPoint.location distanceFromLocation:userLocation];

    if(distance > otherDistance){
        return NSOrderedAscending;
    } else if(distance < otherDistance){
        return NSOrderedDescending;
    } else {
        return NSOrderedSame;
    }
}

I'm trying to sort the array using the following function, but I can't pass my location to the selector:

- (NSArray*)getPointsByDistance:(CLLocation*)location
{
    return [points sortedArrayUsingSelector:@selector(compareByDistance:withLocation:)];
}

2 Answers 2

9

Besides sortedArrayUsingFunction:context: (already well explained by Vladimir), if you're targeting iOS 4.0 and up you could use sortedArrayUsingComparator:, as the passed location can be referenced from within the block. It would look something like this:

- (NSArray*)getPointsByDistance:(CLLocation*)location
{
    return [points sortedArrayUsingComparator:^NSComparisonResult(id a, id b) {
        int distance = [a distanceFromLocation:location];
        int otherDistance = [b distanceFromLocation:location];

        if(distance > otherDistance){
            return NSOrderedAscending;
        } else if(distance < otherDistance){
            return NSOrderedDescending;
        } else {
            return NSOrderedSame;
        }
    }];
}

You could, of course, call your existing method from within the block if you so desire.

Sign up to request clarification or add additional context in comments.

2 Comments

A block is a really nice solution here IMO.
this solution is exactly what I was trying to do. Vladimir's solution gets the job done, but this one is prettier ;)
2

Probably it will be more convenient to sort array using sortedArrayUsingFunction:context: method in your case. You can even utilise comparing selector you already have:

NSComparisonResult myDistanceSort(POI* p1, POI* p2, void* context){
     return [p1 compareByDistance:p2 withLocation:(CLLocation*)context];
}
...
- (NSArray*)getPointsByDistance:(CLLocation*)location
{
    return [points sortedArrayUsingFunction:myDistanceSort context:location];
}

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.