【发布时间】:2010-11-08 00:56:03
【问题描述】:
我有一个 CLLocation 对象数组,我希望能够比较它们以获取与起始 CLLocation 对象的距离。数学很简单,但我很好奇是否有一个方便的排序描述符来做这件事?我应该避免 NSSortDescriptor 并编写自定义比较方法 + 冒泡排序吗?我通常最多比较 20 个对象,因此不需要非常高效。
【问题讨论】:
标签: iphone cocoa sorting geolocation core-location
我有一个 CLLocation 对象数组,我希望能够比较它们以获取与起始 CLLocation 对象的距离。数学很简单,但我很好奇是否有一个方便的排序描述符来做这件事?我应该避免 NSSortDescriptor 并编写自定义比较方法 + 冒泡排序吗?我通常最多比较 20 个对象,因此不需要非常高效。
【问题讨论】:
标签: iphone cocoa sorting geolocation core-location
您可以为 CLLocation 编写一个简单的 compareToLocation: 类别,根据自身与其他 CLLocation 对象之间的距离返回 NSOrderedAscending、NSOrderedDescending 或 NSOrderedSame。然后简单地做这样的事情:
NSArray * mySortedDistances = [myDistancesArray sortedArrayUsingSelector:@selector(compareToLocation:)];
编辑:
像这样:
//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;
}
【讨论】:
只是为了添加到类别响应中(这是要走的路),不要忘记您实际上不需要自己做任何数学运算,您可以使用 CLLocation 实例方法:
- (CLLocationDistance)getDistanceFrom:(const CLLocation *)location
获取两个位置对象之间的距离。
【讨论】:
为了改进 Dave 的回答...
从 iOS 4 开始,您可以使用比较器块,而不必使用静态变量和类别:
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;
}
}];
【讨论】: