2016-05-01 5 views
0

配列は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、またはこれに類するものがありますか?あなたがCLLocationの配列を持っている場合

+0

は、次のとおりです。

他の回答も 最後のもの

OPを使用した溶液以外の他の重複を削除します確かにそれは配列ですか? – Carpsen90

+0

この例は、構文に合った配列ではありません。私は自分でそれをタイプしました。場所は配列です。 –

答えて

2
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) 

必要なものを誤解実際には、この中でそれらを使用しないことをお勧めされるだろう、必要はありません場合。最後の要素と異なる要素を見つけたら、すべての要素の読み込みを停止する必要があるからです。

そして@Eendjeよう

は言った:

   while !locations.isEmpty && (LocationInterface.sharedInterface.distanceBetweenLocations(first: locations.dropLast().last!, last: locations.last!) > 15) 
+0

ここで 'dropLast'をうまく使います。あまりにも多くのステップが必要なので私は私の答えが好きではなかった、あなたの見栄えははるかに良い。 – Eendje

+0

美しい実装。いくつかの不正確さを受け入れるためにこれを微調整しようとし、それが私のために働くならあなたの解決策を受け入れます。 –

1

まず第一に、それはおそらく、今、私たちはSet

このような
var added = Set<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)] 

のようになります

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

1

これを行うには、複雑な時間を要するため、順序付けられたセットデータ構造の実装が必要です。以下は、the OrderedSet libraryに依存する純粋なSwiftソリューションでこれを達成する方法を示しています。

あなたの緯度経度&ペアタイプとしてNSObjectのサブクラスを使用してもかまわない場合…your location objects…は、緯度と経度をラップあなたNSObjectのサブクラスを指し、あなたはNSOrderedSet(array:…your location objects…).arrayでこれを行うことができます。 Locationクラスに-hash-isEqual:を実装する必要があります。つまり、下のサンプルコードの原則は非常に似ています。緯度が&の経度ペアを含む型が必要です(洗濯可能(NSObjectサブクラスでは-hashをオーバーライド)、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. 
} 
1
let lastIndex = array.count - 1 

if array[lastIndex] == array[lastIndex - 1] { 
array.removeLast() 
} 

そのような何かが働くだろう。あなたの特定のニーズに合わせて調整する必要があるかもしれません。

*編集 - これらの他のソリューションは、より複雑に見えるかもしれない、私はあなたがMapReduce、またはFilterを使用して

関連する問題