如何用高阶函数查找数组中距离当前坐标最近的5个元素
优化方案:用高阶函数找到最近的5个坐标
嘿,我来帮你搞定这个问题!你之前用硬编码经纬度范围的方法确实有局限性——万一最近的点刚好在你设定的范围之外,那就直接漏掉了,而且没法精确选出最近的5个,只能筛选出范围内的点。下面用高阶函数给你一个更灵活、准确的解决方案:
核心思路
- 给每个坐标计算到当前点的距离(用距离平方代替实际距离可以提升性能,排序结果完全一致)
- 把坐标和对应的距离绑定配对
- 按距离从小到大排序
- 取前5个目标坐标
代码实现(Swift为例)
首先定义你的基础数据:
let currentLatitude = 19.1553902 let currentLongitude = 72.8528602 let coordinates = [[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]]
然后用高阶函数链式处理:
// 1. 给每个坐标计算距离平方,并和原坐标绑定 let coordsWithDistance = coordinates.map { coord -> (coordinate: [Double], distanceSquared: Double) in let latDiff = coord[0] - currentLatitude let lonDiff = coord[1] - currentLongitude // 用距离平方代替实际距离,避免开根号,计算更快 return (coord, latDiff * latDiff + lonDiff * lonDiff) } // 2. 按距离从小到大排序,取前5个,再提取坐标 let nearest5Coordinates = coordsWithDistance .sorted { $0.distanceSquared < $1.distanceSquared } // 按距离升序排序 .prefix(5) // 取前5个 .map { $0.coordinate } // 只保留坐标数据 // 打印结果看看 print("最近的5个坐标:\(nearest5Coordinates)")
可选:更精确的球面距离计算
如果你的坐标跨度很大(比如跨城市),平面距离的误差会比较明显,这时候可以用Haversine公式计算真实的球面距离(单位:公里):
// 实现Haversine公式 func haversineDistance(lat1: Double, lon1: Double, lat2: Double, lon2: Double) -> Double { let earthRadius = 6371.0 // 地球平均半径,公里 let dLat = (lat2 - lat1).degreesToRadians let dLon = (lon2 - lon1).degreesToRadians let a = sin(dLat/2) * sin(dLat/2) + cos(lat1.degreesToRadians) * cos(lat2.degreesToRadians) * sin(dLon/2) * sin(dLon/2) let c = 2 * atan2(sqrt(a), sqrt(1-a)) return earthRadius * c } // 给Double添加角度转弧度的扩展 extension Double { var degreesToRadians: Double { return self * .pi / 180 } }
然后修改计算逻辑:
let coordsWithExactDistance = coordinates.map { coord -> (coordinate: [Double], distance: Double) in let distance = haversineDistance(lat1: currentLatitude, lon1: currentLongitude, lat2: coord[0], lon2: coord[1]) return (coord, distance) } let nearest5Exact = coordsWithExactDistance .sorted { $0.distance < $1.distance } .prefix(5) .map { $0.coordinate }
为什么这个方案更好?
- 灵活性高:不用硬编码范围,所有坐标都会参与计算,不会漏掉任何潜在的近点
- 代码简洁:用
map、sorted、prefix这些高阶函数链式调用,逻辑清晰易读 - 性能可选:小范围用距离平方足够快,大范围用Haversine保证精度
内容的提问来源于stack exchange,提问作者Ramesh
相关产品推荐
相关产品推荐

