С кортежами работать нелегко, я рекомендую сначала обернуть ваши данные в пользовательский объект:
import CoreLocation
struct MyLocation: Hashable {
let name: String
let coordinate: CLLocation
init(tuple: (String, Double, Double)) {
name = tuple.0
coordinate = CLLocation(latitude: tuple.1, longitude: tuple.2)
}
public static func == (lhs: MyLocation, rhs: MyLocation) -> Bool {
return
lhs.name == rhs.name
&& lhs.coordinate.distance(from: rhs.coordinate) < 1
}
public var hashValue: Int {
return name.hashValue
}
}
Как видите, я уже объявил Equatable
, а также Hashable
для простотыindexing.
Тогда мы можем использовать простое расширение Array
:
extension Array where Element: Hashable {
func distinct() -> [Element] {
var uniqueValues: Set<Element> = []
return self.filter {
let (inserted, _) = uniqueValues.insert($0)
return inserted
}
}
}
И использовать его для наших данных:
var locations = [("Location_A", 49.5858, 9.123456), ("Location_B", 49.5858, 9.123456), ("Location_A", 49.5855, 9.123450)]
let myLocations = locations
.map { MyLocation(tuple: $0) }
.distinct()
print(myLocations)
Обратите внимание, что я определил равенстводля двух объектов, когда они ближе, чем 1 метр.Это будет медленнее, чем простое сравнение долготы с долготой и широты с широтой, но также будет более точным.