如何通过iOS与距离对数组进行排序

Kei*_*ith 2 objective-c ios

我还在学习目标C和iOS,而且我遇到了一个问题.我正在从CoreData创建一个包含纬度和经度的数组.我想拿这个数组并按最近的位置排序.

这是我到目前为止:

NSError *error = nil;
NSFetchRequest *getProjects = [[NSFetchRequest alloc] init];
NSEntityDescription *projectsEntity = [NSEntityDescription entityForName:@"TimeProjects" inManagedObjectContext:context];

[getProjects setEntity:projectsEntity];
projectArray = [[context executeFetchRequest:getProjects error:&error] mutableCopy];

for (NSObject *project in projectArray) {
    // Get location of house
    NSNumber *lat = [project valueForKey:@"houseLat"];
    NSNumber *lng = [project valueForKey:@"HouseLng"];


    CLLocationCoordinate2D coord;
    coord.latitude = (CLLocationDegrees)[lat doubleValue];
    coord.longitude = (CLLocationDegrees)[lng doubleValue];

    houseLocation = [[CLLocation alloc] initWithLatitude:coord.latitude longitude:coord.longitude];
    //NSLog(@"House location: %@", houseLocation);

    CLLocationDistance meters = [houseLocation distanceFromLocation:currentLocation];

}
Run Code Online (Sandbox Code Playgroud)

我也有这个排序代码,但我不知道如何将两者放在一起.

[projectArray sortUsingComparator:^NSComparisonResult(id o1, id o2) {
    CLLocation *l1 = o1, *l2 = o2;

    CLLocationDistance d1 = [l1 distanceFromLocation:currentLocation];
    CLLocationDistance d2 = [l2 distanceFromLocation:currentLocation];
    return d1 < d2 ? NSOrderedAscending : d1 > d2 ? NSOrderedDescending : NSOrderedSame;
}];
Run Code Online (Sandbox Code Playgroud)

有人可以帮助我让这两件事一起工作吗?

Mar*_*n R 6

您的sortUsingComparator块需要CLLocation对象,而不是Core Data类的实例.这很容易解决,但我建议的是:

  • 向您的实体添加瞬态属性currentDistance.(瞬态属性不存储在持久性存储文件中.)类型应为"Double".
  • 获取对象后,计算currentDistance所有对象projectArray.
  • 最后projectArray使用currentDistance键上的排序描述符对数组进行排序.

优点是到当前位置的距离仅针对每个对象计算一次,而不是在比较器方法中重复计算.

代码看起来像这样(不是编译器检查!):

NSMutableArray *projectArray = ... // your mutable copy of the fetched objects
for (TimeProjects *project in projectArray) {
    CLLocationDegrees lat = [project.houseLat doubleValue];
    CLLocationDegrees lng = [project.houseLng doubleValue];
    CLLocation *houseLocation = [[CLLocation alloc] initWithLatitude:lat longitude:lng];
    CLLocationDistance meters = [houseLocation distanceFromLocation:currentLocation];
    project.currentDistance = @(meters);
}
NSSortDescriptor *sort = [NSSortDescriptor sortDescriptorWithKey:@"currentDistance" ascending:YES]
[projectArray sortUsingDescriptors:@[sort]];
Run Code Online (Sandbox Code Playgroud)

或者,您可以创建实体currentDistance持久属性,并在创建或修改对象时对其进行计算.优点是您可以根据currentDistance获取请求添加排序描述符,而不是先获取和后续排序.当然,缺点是当前位置发生变化时必须重新计算所有值.