检查数组是否具有相同的纬度经度 swift

Check if array has same Latitude Longitude swift

我有一个 class 有那些数据

class Events {
   var name: String!
   var latitude: Double!
   var longitude: Double!
}

然后我用 json 的数据填充它。

所以有些事件具有相同的纬度和经度,但它们不是连续的,我的意思是它不是 event3 与 event4 等相同

所以我想在地图上显示它们

填写这个数组

var events = [Events]()

在这个 for 循环中,我正在制作引脚。

 for events in events {
            let annotation = MKPointAnnotation()
            annotation.title = events.name

            annotation.coordinate = CLLocationCoordinate2D(latitude: events.latitude, longitude: events.longitude)
            mapView.addAnnotation(annotation)
        }

如何在部署图钉之前进行快速搜索,查看一个图钉是否与另一个图钉具有相同的纬度和经度,添加一些数字以显示它们都接近?

非常感谢!

使用Set 查找唯一实例。为了使用 Set 你的基本元素,在这种情况下 Events 必须是 Hashable 并且暗示 Equatable:

class Events : Hashable {
    var name: String!
    var latitude: Double!
    var longitude: Double!

    // implement Hashable        
    var hashValue: Int {
        return latitude.hashValue | longitude.hashValue
    }

    // Implement Equatable
    static func ==(lhs:Events, rhs:Events) -> Bool {
        return lhs.latitude == rhs.latitude && lhs.longitude == rhs.longitude
    }
}

然后你的主循环是你已有的直接扩展,请注意,这会将所有匹配项折叠成一个点并更改名称以指示有多少匹配项:

// Use a Set to filter out duplicates
for event in Set<Events>(events) {
    let annotation = MKPointAnnotation()
    // Count number of occurrences of each item in the original array
    let count = events.filter { [=11=] == event }.count

    // Append (count) to the title if it's not 1
    annotation.title = count > 1 ? "\(event.name) (\(count))" : event.name

    // add to the map
}

相反,如果您想移动点以使它们不堆叠,那么您想要类似的东西,我们在其中建立一组占用的位置并改变点以将它们移动很少。

func placeEvents(events:[Events], mapView:MKMapView) {
    var placed = Set<Events>()

    for event in events {
        if placed.contains(event) {
            // collision: mutate the location of event as needed,
        }

        // Add the mutated point to occupied points
        placed.formUnion([event])

        // Add the point to the map here
    }
}

如果预期值不完全相同,而只是在例如彼此的 .0001 范围内,那么您可以将以下内容用于 hashValue==

fileprivate let tolerance = 1.0 / 0.0001

private var tolerantLat : Long { return Long(tolerance * latitude) }
private var tolerantLon : Long { return Long(tolerance * longitude) }

var hashValue : Int {
    return tolerantLat.hashValue | tolerantLon.hashValue
}

static func ==(lhs:Events, rhs:Events) -> Bool {
    return lhs.tolerantLat == rhs.tolerantLat && lhs.tolerantLon == rhs.tolerantLon
}