我有一个CLLocations
数组。我的目标是找到阵列中与位置相同的最后位置,然后删除以下所有对象。
示例:
[lat: 11.123, long: 11.123,
lat: 12.345, long: 123.123,
lat: 14.124, long: 14.124,
lat: 16.1661, long: 16.1616,
lat: 15.1515, long: 15.1515,
lat: 15.1515, long: 15.1515, //Remove
lat: 15.1515, long: 15.1515] //Remove
我想改变它们存储的数组,而不是创建一个新数组。
到目前为止我的尝试:
var reversedLocations = Array(locations.reverse())
for (index,location) in reversedLocations.enumerate() {
if index+1 <= reversedLocations.count-1 {
let distanceToNext = LocationInterface.sharedInterface.distanceBetweenLocations(first: location, last: locations[index+1])
if distanceToNext < 10 {
reversedLocations.removeAtIndex(reversedLocations.indexOf(location)!)
toDate = reversedLocations.first!.timestamp
}
}
}
但是这段代码令人困惑,我不确定它是最好的方法。这个函数只是乱七八糟,因为我改变了数组的枚举,所以索引不正确。是否有任何Array.reduce,.sort,.map或类似的人可以帮我解决这个问题?
答案 0 :(得分:2)
(count 48)
=> 1
(count 4881)
=> 4
(count 8818)
=> 5
使用var locations = [1, 2, 3, 4, 5, 5, 5, 1, 2, 3, 4, 3, 3, 3]
while !locations.isEmpty && locations.dropLast().last == locations.last
{
locations.removeLast()
}
print(locations)
,Map
或Reduce
不是必需的,实际上建议在这种情况下不要使用它们。因为一旦找到与上一个元素不同的元素,就应该停止阅读所有元素。
和@Eendje说:
其他答案也会删除除了以外的任何其他重复项 最后一个
OP使用的解决方案:
Filter
答案 1 :(得分:1)
首先,如果你有一个CLLocation
数组,那么它可能看起来像这样
let locations: [CLLocation] = [
CLLocation(latitude: 11.123, longitude: 11.123),
CLLocation(latitude: 12.345, longitude: 123.123),
CLLocation(latitude: 14.124, longitude: 14.124),
CLLocation(latitude: 16.1661, longitude: 16.1616),
CLLocation(latitude: 15.1515, longitude: 15.1515),
CLLocation(latitude: 15.1515, longitude: 15.1515),
CLLocation(latitude: 15.1515, longitude: 15.1515)]
现在我们可以像这样创建一个Set
var added = Set<CLLocation>()
最后过滤数组
let filtered = locations.filter { (location) -> Bool in
let duplicate = added.contains { (location.coordinate.latitude, location.coordinate.longitude) == ($0.coordinate.latitude, $0.coordinate.longitude) }
guard !duplicate else { return false }
added.insert(location)
return true
}
现在您的结果位于filtered
。
答案 2 :(得分:1)
要做到这一点,时间复杂度很高,您需要一个有序的数据结构实现。下面我将展示如何使用依赖the OrderedSet library的纯Swift解决方案来实现这一目标。
如果你不介意使用NSObject子类作为你的纬度&amp;经度对类型,您可以使用NSOrderedSet(array:…your location objects…).array
执行此操作,其中…your location objects…
指的是包含纬度和经度的NSObject子类。您需要向-hash
课程实施-isEqual:
和Location
。也就是说,下面示例代码中的原理非常相似:您需要一个包含纬度和范围的类型。经度对,可以清洗(在你的NSObject子类中覆盖-hash
)和equatable(在你的NSObject中覆盖-isEqual:
)。
import Darwin
import SortedSet
struct Location:Hashable {
let lat:Double
let long:Double
var hashValue: Int {
// This is a *terrible* hash function.
// You'll find instructions from elsewhere for more performant ones.
return Int(ceil(lat + long))
}
}
func ==(lhs: Location, rhs: Location) -> Bool {
return lhs.lat == rhs.lat && lhs.long == rhs.long
}
let orderedLocations = OrderedSet<Location>(sequence: [Location(lat: 11.123, long: 11.123),
Location(lat: 12.345, long: 123.123),
Location(lat: 14.124, long: 14.124),
Location(lat: 16.1661, long: 16.1616),
Location(lat: 15.1515, long: 15.1515),
Location(lat: 15.1515, long: 15.1515),
Location(lat: 15.1515, long: 15.1515)])
for location in orderedLocations {
print(location) // prints out the locations in the original order, with duplicates removed.
}
答案 3 :(得分:1)
let lastIndex = array.count - 1
if array[lastIndex] == array[lastIndex - 1] {
array.removeLast()
}
这样的事情会起作用。您可能需要调整它以满足您的特定需求。
*编辑 - 这些其他解决方案看起来更复杂,也许我误解了你的需求