You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Swift中使用Filter移除坐标数组中的重复位置坐标?

在Swift中使用Filter移除CLLocationCoordinate2D数组的重复项

当然可以用filter方法来实现!问题的核心在于CLLocationCoordinate2D没有遵循Equatable或Hashable协议,所以没法直接用常规的去重逻辑。不过我们可以通过将坐标转换为可哈希的类型,配合filter和一个辅助集合来完成去重。

方法1:精确匹配坐标

如果需要严格匹配经纬度的每一位小数,可以把CLLocationCoordinate2D转换成包含经纬度的元组(Double类型是Hashable的,所以元组可以存入Set),然后在filter中维护一个已访问坐标的集合:

var seenCoordinates = Set<(latitude: Double, longitude: Double)>()

let uniqueCoordinates = coodinatesArray.filter { coordinate in
    // 将坐标转换为可哈希的元组
    let coordinateKey = (latitude: coordinate.latitude, longitude: coordinate.longitude)
    // 检查是否已经见过这个坐标
    guard !seenCoordinates.contains(coordinateKey) else {
        return false // 已存在,过滤掉
    }
    // 标记为已访问
    seenCoordinates.insert(coordinateKey)
    return true // 保留当前坐标
}

方法2:忽略微小精度差异(更实用)

在实际场景中,GPS坐标经常会有微小的精度误差(比如你数组里的那对接近的坐标),如果需要把这类近似坐标视为重复项,可以先对经纬度进行四舍五入,再进行去重:

// 辅助函数:将坐标四舍五入到指定小数位
func roundedCoordinate(_ coordinate: CLLocationCoordinate2D, toDecimalPlaces places: Int) -> (latitude: Double, longitude: Double) {
    let multiplier = pow(10, Double(places))
    let roundedLat = round(coordinate.latitude * multiplier) / multiplier
    let roundedLon = round(coordinate.longitude * multiplier) / multiplier
    return (roundedLat, roundedLon)
}

var seenCoordinates = Set<(latitude: Double, longitude: Double)>()
let uniqueCoordinates = coodinatesArray.filter { coordinate in
    // 先四舍五入再生成匹配键
    let coordinateKey = roundedCoordinate(coordinate, toDecimalPlaces: 6)
    guard !seenCoordinates.contains(coordinateKey) else {
        return false
    }
    seenCoordinates.insert(coordinateKey)
    return true
}

原理说明

  • filter会遍历数组的每个元素,我们通过闭包决定是否保留当前元素
  • 用Set来记录已经处理过的坐标,因为Set的查找和插入操作都是O(1)的,效率很高
  • 由于CLLocationCoordinate2D本身不可哈希,我们用元组作为“代理键”来完成重复判断

内容的提问来源于stack exchange,提问作者Abin Baby

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.29 06:52:04