NSSortDescriptor for comparing CLLocation objects in Cocoa / iPhone

I have an array of CLLocation objects, and I would like to be able to compare them to get the distance from the original CLLocation object. The math is straightforward, but I'm curious if there is a convenience sort handle to do this? Should I avoid NSSortDescriptor and write my own comparison method + bubble sort? Usually I compare no more than 20 objects, so it should not be super efficient.

+3
source share
3 answers

You can write a simple compareToLocation: category for CLLocation that returns NSOrderedAscending, NSOrderedDescending, or NSOrderedSame depending on the distance between itself and another CLLocation object. Then just do the following:

NSArray * mySortedDistances = [myDistancesArray sortedArrayUsingSelector:@selector(compareToLocation:)];

Edit:

Like this:

//CLLocation+DistanceComparison.h
static CLLocation * referenceLocation;
@interface CLLocation (DistanceComparison)
- (NSComparisonResult) compareToLocation:(CLLocation *)other;
@end

//CLLocation+DistanceComparison.m
@implementation CLLocation (DistanceComparison)
- (NSComparisonResult) compareToLocation:(CLLocation *)other {
  CLLocationDistance thisDistance = [self distanceFromLocation:referenceLocation];
  CLLocationDistance thatDistance = [other distanceFromLocation:referenceLocation];
  if (thisDistance < thatDistance) { return NSOrderedAscending; }
  if (thisDistance > thatDistance) { return NSOrderedDescending; }
  return NSOrderedSame;
}
@end


//somewhere else in your code
#import CLLocation+DistanceComparison.h
- (void) someMethod {
  //this is your array of CLLocations
  NSArray * distances = ...;
  referenceLocation = myStartingCLLocation;
  NSArray * mySortedDistances = [distances sortedArrayUsingSelector:@selector(compareToLocation:)];
  referenceLocation = nil;
}
+14
source

To improve Dave's answer ...

As in iOS 4, you can use the comparator block and avoid using a static variable and category:

NSArray *sortedLocations = [self.locations sortedArrayUsingComparator:^NSComparisonResult(CLLocation *obj1, CLLocation *obj2) {
    CLLocationDistance distance1 = [targetLocation distanceFromLocation:loc1];
    CLLocationDistance distance2 = [targetLocation distanceFromLocation:loc2];

    if (distance1 < distance2)
    {
        return NSOrderedAscending;
    }
    else if (distance1 > distance2)
    {
        return NSOrderedDescending;
    }
    else
    {
        return NSOrderedSame;
    }
}];
+2
source

( ), , - , CLLocation:

- (CLLocationDistance)getDistanceFrom:(const CLLocation *)location

.

+1

Source: https://habr.com/ru/post/1711835/


All Articles