在数组中查找最近的5个元素

时间:2018-03-23 04:13:09

标签: ios swift sorting swift4

当前位置值 -

let currentLatitide = 19.1553902

le currentLongitude = 72.8528602

坐标的演示模型是

[[19.5,71.0],[18.5,72.0],[19.15,72.85],[19.1,75.0],[19.2,70.0],[19.3,70.0],[19.4,70.0],[19.6,70.0],[19.7,70.2],[19.9,70.3],[25,62.0],[24.5,73.4],[23.5,65.0],[21.5,68.0],[20.5,69.0]]

我正在寻找与currentLatitidecurrentLongitude

相对应的 5 最接近的值

我试过像

这样的Bad解决方案
    for value in modelBeacons {
         if value.latitude > 19.13 && value.latitude < 19.17 && value.longitude > 72.82 && value.longitude < 72.88 {
         print("Nearest will be here")
     } 

但我正在寻找更好的解决方案,例如使用 map / filter / High order function 功能。

2 个答案:

答案 0 :(得分:4)

将当前位置转换为CLLocation。

将坐标数组映射到包含坐标和当前位置距离的结构数组(在map语句中,从数组中的每个坐标创建一个临时CLLocation,并使用distance(from:)计算距离。)

然后按距离对结果数组进行排序,并使用array.prefix(_:)

从数组中取出前5个项目

请注意distance(from:)使用&#34;大圆圈&#34; 3D trig用于计算距离,因此将纬度/长度视为笛卡尔坐标并使用距离公式会更慢,但它会更准确。如果你的距离小于50公里,那么做笛卡尔数学应该足够准确。

import CoreLocation
let currentLatitide = 19.1553902
let currentLongitude = 72.8528602
struct CoordStruct: CustomStringConvertible {
    let coord: CLLocationCoordinate2D
    let distance: Double

    var description: String {
        return "lat: " + String(format: "%.4f",coord.latitude) +
            ", long: " + String(format: "%.4f",coord.longitude) + ", distance: " + distance.description
    }
}

let location = CLLocation(latitude: currentLatitide, longitude: currentLongitude)

 let points =   [[19.5,71.0],[18.5,72.0],[19.15,72.85],[19.1,75.0],[19.2,70.0],[19.3,70.0],[19.4,70.0],[19.6,70.0],[19.7,70.2],[19.9,70.3],[25,62.0],[24.5,73.4],[23.5,65.0],[21.5,68.0],[20.5,69.0]]

let structs: [CoordStruct] = points.map {
    let thisCoord = CLLocationCoordinate2D(latitude: $0[0], longitude: $0[1])
    let thisLocation = CLLocation(latitude:$0[0], longitude: $0[1])
    let distance = location.distance(from: thisLocation)
    return CoordStruct(coord: thisCoord, distance: distance)
    }
    .sorted { $0.distance < $1.distance }
let first5Structs = structs.prefix(5)

first5Structs.forEach { print($0) }

输出:

lat: 19.1500, long: 72.8500, distance: 668.232670102048
lat: 18.5000, long: 72.0000, distance: 115513.034301754
lat: 19.5000, long: 71.0000, distance: 198407.990357831
lat: 19.1000, long: 75.0000, distance: 225952.852274862
lat: 19.9000, long: 70.3000, distance: 280913.847369699

答案 1 :(得分:1)

let array = [[19.5,71.0],[18.5,72.0],[19.15,72.85],[19.1,75.0],[19.2,70.0],[19.3,70.0],[19.4,70.0],[19.6,70.0],[19.7,70.2],[19.9,70.3],[25,62.0],[24.5,73.4],[23.5,65.0],[21.5,68.0],[20.5,69.0]]

let coordinate = CLLocation(latitude: 19.1553902, longitude: 72.8528602)

let distanceArray = array.map({ coordinate.distance(from: CLLocation(latitude: $0[0], longitude: $0[1])) } )

distanceArray = distanceArray.sorted()
distanceArray.prefix(5)

// print(distanceArray) : [668.23267010204756, 115513.03430175369, 198407.99035783144, 225952.85227486189, 280913.84736969916]