我试图按距离当前位置的距离对数组进行排序。首先,您会看到organizationObject
,其中包含不同的值,然后我们的位置是不同位置的数组。它是array
的原因是因为组织可以有多个位置。然后在我的ViewController中创建一组测试对象并附加到数组。我的问题是如何根据distanceFromLocation对orgArray
进行排序?如果位置数组中有多个位置,则应采用最接近的位置。
OrganizationObject
class OrganizationObject {
var id: Int
var name: String
var image: UIImage
var locations: [CLLocationCoordinate2D]
init(id: Int, name: String, image: UIImage, locations: [CLLocationCoordinate2D]) {
self.id = id
self.name = name
self.image = image
self.locations = locations
}
}
将测试对象附加到数组。在viewDidLoad
中orgArray.append(OrganizationObject(id: 0, name: "Statens Museum For Kunst", image: UIImage(named: "statensmuseum.jpg")!, locations: [CLLocationCoordinate2D(latitude: 55.6888127, longitude: 12.578330300000061)]))
orgArray.append(OrganizationObject(id: 0, name: "7 eleven", image: UIImage(named: "7eleven.jpg")!, locations: [CLLocationCoordinate2D(latitude: 58.334682, longitude: 8.231820900000002)]))
orgArray.append(OrganizationObject(id: 0, name: "Kongens have", image: UIImage(named: "kongenshave.jpg")!, locations: [CLLocationCoordinate2D(latitude: 55.6852905, longitude:12.579845200000022)]))
orgArray.append(OrganizationObject(id: 0, name: "Magasin du nord", image: UIImage(named: "magasin.jpg")!, locations: [CLLocationCoordinate2D(latitude: 50.6456604, longitude: 3.053486600000042), CLLocationCoordinate2D(latitude: 55.7835017, longitude: 12.370985799999971)]))
答案 0 :(得分:5)
这是一个解决方案。由于以下几个原因,直接调用排序函数会稍微复杂一些:首先需要找到组织中最近的位置,如问题中所提到的,其次是在{{1}内使用的半正式计算这一事实如果天真地使用,CLLocation
方法会减慢速度。
出于这些原因,我创建了一个特殊对象来进行排序,这样我就可以使用成员字典来memoize调用distanceFromLocation:
的结果。这不会对测试数据产生影响,但如果您需要处理大量的地方,这将很重要。
作为旁注 - 如果distanceFromLocation
存储OrganizationObject
而不是CLLocation
,则可能会使事情变得更简单一点 - 尽管这是一个相当小的问题。
以下是代码:
CLLocationCoordinate
我已根据您的示例数据对其进行了测试,使用哥本哈根Christiansborg Palace的位置作为测试位置,并按以下顺序进行测试:
class OrganizationSorter {
var memoizedValues = [Int:CLLocationDistance]()
private func shortestDistanceToOrganizationFromLocation(organization:OrganizationObject,location:CLLocation) -> CLLocationDistance? {
let memoizedValue = memoizedValues[organization.id] //Check whether we've done this calculation before, if so return the result from last time
if memoizedValue != nil {
return memoizedValue
}
//There should probably be some code around here to check
//that the organization object has at least one location
//I'm assuming it does to simplify things
var shortestDistance : CLLocationDistance? = nil
let locations = organization.locations
if locations.count > 0 {
for coord in locations {
let loc = CLLocation(latitude: coord.latitude, longitude: coord.longitude)
let dist = loc.distanceFromLocation(location)
if shortestDistance == nil || shortestDistance > dist {
shortestDistance = dist
}
}
}
if shortestDistance != nil {
memoizedValues[organization.id] = shortestDistance
}
return shortestDistance
}
func sortOrganizationsByDistanceFromLocation(orgArray:[OrganizationObject],location:CLLocation) -> [OrganizationObject] {
let sortedArray = orgArray.sort { (a:OrganizationObject, b:OrganizationObject) -> Bool in
let dist1 = self.shortestDistanceToOrganizationFromLocation(a, location: location)
let dist2 = self.shortestDistanceToOrganizationFromLocation(b, location: location)
return dist1 < dist2
}
memoizedValues.removeAll() //reset memoized values in case object is used twice
return sortedArray
}
}
似乎与给定的坐标相匹配 - 看起来像Magasin du Nord最近的坐标是在哥本哈根郊区的一个小镇的某个地方(另一个在里尔?),而且11个在瑞典。 / p>
以下是如何使用类(使用原始问题中的测试数据,Kongens have
Statens Museum For Kunst
Magasin du nord
7 eleven
中的id
值已更改,因此它们不是全0(否则代码将无法正常工作) )。
OrganizationObject