【问题标题】:How to sort array of objects(latitude, longitude) by nearest distance?如何按最近距离对对象数组(纬度,经度)进行排序?
【发布时间】:2014-01-22 04:11:35
【问题描述】:

我有一个来自核心数据的数组,我正在思考如何按最近的距离对数组进行排序:

for (int i=0; i<allTasks.count; i++) {
        id singleTask = allTasks[i];
        double latitude = [singleTask[@"latitude"] doubleValue];
        double longitude = [singleTask[@"longitude"] doubleValue];
    }

编辑: 当前位置与数组中所有位置之间的距离。 我知道如何计算距离,我不知道如何排序。

【问题讨论】:

  • 你做一件事,首先计算两个坐标之间的距离,用 dict Contanin lat long 和 dist 键将它们存储在 arra 中,并将其存储在数组中,然后用 discriptor 短它
  • 计算距离并按其排序。你自己回答了你的问题。计算距离有问题吗?
  • 之间的距离...
  • 是的,有纬度和经度,您可以计算与当前经度的距离
  • 我编辑了我的问题。

标签: ios objective-c arrays sorting latitude-longitude


【解决方案1】:

您可以计算两点之间的距离,例如this

您也可以试试这个https://stackoverflow.com/a/9104926/3151066 并定义一些计算距离的方法,以满足您作为比较运算符的要求

【讨论】:

  • 不适用,因为他必须混合两个字段才能获得距离
  • 核心数据不能在 fetch 中使用 CoreLocation ;)
  • 是的,但在我链接的问题的一个答案中,描述了一种以标准方式对数组进行排序的方法,因此您可以在那里定义一个复杂的条件来确定顺序
  • 那么请删除第一个链接。我担心答案会反复无常——我们甚至都不知道他想要什么
  • @Daij-Djan 以您现在建议的方式编辑我认为我的回答是一致的,应该足够了
【解决方案2】:

那么你想对你的 allTask​​s 数组进行排序吗?

最好的办法是为每个 singleTask 对象添加一个距离键/值对,并持有一个双 NSNumber。

在第一遍中,循环遍历 allTask​​s 数组,获取每个纬度/经度,使用它来创建 CLLocation,并使用 CLLocation 方法 distanceFromLocation: 计算每个位置与目标(当前?)位置之间的距离。将结果保存到数组中的每个 singleTask 对象中。

一旦您的 allTask​​s 数组包含距离属性,只需使用 sortUsingComparator 等排序方法之一即可根据距离值对数组进行排序。 (在 sortUsingComparator 系列方法中,您提供了一个比较器块,系统使用它来比较对象对。然后它在您的数组上运行排序算法,使用您的比较器来决定排序顺序。

【讨论】:

    【解决方案3】:
    1. 获取当前位置的 CLLocation(通过 CLLocationManager 完成)

    2. 计算每个项目的距离并将距离+项目作为一对存储在字典中

    3. 排序字典 allKeys 数组并进行比较:选择器

    所以

    CLLocation *current = ...;
    NSMutableDictionary *distsAndTasks [NSMutableDictionary dictionary];
    
    for(id task in allTasks) {
        CLLocation *taskLoc = [[CLLocation alloc] initWithLatitude:task.lat longitude:task.long];//!
        CLLocationDistance dist = [taskLoc distanceFrom:current];
        if(distsAndTasks[@(dist)]) {
            NSMutableArray *equidstants = [distsAndTasks[@(dist)] mutableCopy];
            [equidstants addObject:task]; 
            distsAndTasks[@(dist)] = equidstants; 
        }
        else {
            distsAndTasks[@(dist)] = @[task]; 
        }
    }
    
    NSArray *sortedDists = [distsAndTasks.allKeys sortedArrayUsingSelector:@selector(compare:)];
    
    //the tasks can now be access in a sorted way
    for(NSNumber *dist in sortedDists) {
        NSArray *tasksAtDistance = distsAndTasks[dist];
        NSLog(@"%@", tasksAtDistance);
    }
    

    【讨论】:

    • 免责声明:100% 内联编写,谨防拼写错误
    • 建议:将距离封装在Task对象本身中。
    • 如果两个或多个任务等距,这将失败。
    • @Daij-Djan 在 Task 对象中存储到其他不相关点的距离可能不合逻辑。喜欢distanceToSomething?错误的。还是distanceToCurrent?那将需要实时更新。不。字典是很好的解决方案,但我会使用 Tasks 作为键distances 作为值,所以重复不会有问题。
    • @Daij-Djan 如果它不支持复制,那么你可以使用一些任务标识符,甚至它的hash。或[NSMapTable strongToStrongObjectsMapTable] :)
    猜你喜欢
    • 2019-09-23
    • 2013-06-28
    • 2015-01-06
    • 1970-01-01
    • 1970-01-01
    • 2013-05-04
    • 1970-01-01
    • 2013-04-30
    • 1970-01-01
    相关资源
    最近更新 更多