【问题标题】:Sort array by calculated distance in Swift在 Swift 中按计算的距离对数组进行排序
【发布时间】:2016-02-04 11:04:55
【问题描述】:

所以我有一个自定义对象数组,它们具有双纬度和双经度值。我想根据从特定点到数组中每个项目的位置的计算距离对数组进行排序。我有一个函数可以根据纬度和经度值计算距离。有没有一种简单的方法来完成这种排序?

【问题讨论】:

    标签: swift


    【解决方案1】:

    假设您的对象有一个模型 Place

    class Place {
        var latitude: CLLocationDegrees
        var longitude: CLLocationDegrees
    
        var location: CLLocation {
            return CLLocation(latitude: self.latitude, longitude: self.longitude)
        }
    
        func distance(to location: CLLocation) -> CLLocationDistance {
            return location.distance(from: self.location)
        }
    }
    

    那么数组var places: [Place]可以这样排序:

    places.sort(by: { $0.distance(to: myLocation) < $1.distance(to: myLocation) })
    

    【讨论】:

    • 你不应该保证与物体的距离。那不是很好的编码风格。仅当您稍后需要它进行缓存时。最好将distance = location.distanceFromLocation(fromLocation!) 更改为return distance = location.distanceFromLocation(fromLocation!) 并按places.sortInPlace({ $0.calculateDistance(YOUR_LOCATION) &lt; $1..calculateDistance(YOUR_LOCATION) }) 订购
    • :) 我很乐意提供帮助 :)
    【解决方案2】:

    解决此问题的另一种方法是在 Array 上进行扩展,允许您按位置排序。这种方法的好处是调用站点更清晰,更易于理解。

    ** 注意 ** - 我已将 class 更改为 struct。但是,这也适用于类。

    struct Place {
        var latitude: CLLocationDegrees
        var longitude: CLLocationDegrees
    
        var location: CLLocation {
            return CLLocation(latitude: self.latitude, longitude: self.longitude)
        }
    
        func distance(to location: CLLocation) -> CLLocationDistance {
            return location.distance(from: self.location)
        }
    }
    

    然后我们像这样声明一个扩展,其中数组的ElementPlace

    extension Array where Element == Place {
    
        mutating func sort(by location: CLLocation) {
             return sort(by: { $0.distance(to: location) < $1.distance(to: location) })
        }
    
        func sorted(by location: CLLocation) -> [Place] {
            return sorted(by: { $0.distance(to: location) < $1.distance(to: location) })
        }
    }
    

    这允许我们使用以下语法按位置排序:

    places.sort(by: myLocation) // 变异版本

    let newPlaces = places.sorted(by: myLocation) // 非变异版本

    【讨论】:

      【解决方案3】:

      这很容易做到。 您计算距离的函数必须采用两个类型的参数,即您要排序的数组中的内容并返回 Bool,例如:

      // I assumed your array stores MyLocation
      func mySortFunc(location1: MyLocation, location2: MyLocation) -> Bool {
      
          // do your calculation here and return true or false
      }
      
      var array: [MyLocation] = ...
      array.sortInPlace { (loc1, loc2) -> Bool in
          mySortFunc(loc1, location2: loc1)
      }
      

      【讨论】:

      • 嗯,为什么排序函数返回一个布尔值?返回值是由什么决定的?这可能很明显,但我在这里有点困惑:)
      • 假设您有一个 Int [2,4,6] 数组,排序函数在第一次迭代中传递给您的函数 2 和 4,如果 2 低于 4,则返回 true,否则返回 false (示例返回 2
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-11-18
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-02-02
      相关资源
      最近更新 更多