我有一个有这些数据的课
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)
}
如何在部署引脚之前进行快速搜索,看看引脚是否与另一个引脚具有相同的lat和lon,添加一些数字只是为了显示它们都接近?
非常感谢!
答案 0 :(得分:3)
使用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 { $0 == 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
和==
< / p>
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
}