2016-07-01 11 views
2

における構造体のプロパティに基づいて、配列内の重複した構造体を削除します。私は、単純な構造体を作り、Equatableプロトコルを実装したスウィフト

extension MyModelStruct: Equatable {} 

func ==(lhs: NModelMatch, rhs: NModelMatch) -> Bool { 
    let areEqual = lhs.id == rhs.id 
    return areEqual 
} 

public struct MyModelStruct { 

    var id : String? 
    var staticId : String? 

    init(fromDictionary dictionary: NSDictionary){ 
     id = dictionary["id"] as? String 
     ... 
} 

その後、私のプロジェクトで、私は[MyModelStruct]の配列を取得、私は何に同じIDを持つMyModelStructをすべて削除することです

let val1 = MyModelStruct(id:9, subId:1) 
let val2 = MyModelStruct(id:10, subId:1) 
let val3 = MyModelStruct(id:9, subId:10) 

var arrayOfModel = [val1,val2,val3]; // or set but i do not know how to use a set 
var arrayCleaned = cleanFunction[M2,M3] 

どうすればcleanFunctionを作成できますか?

誰かが助けてくれますか? ありがとうございます。 Xcode:バージョン7.3.1

答えて

2

Arrayの代わりにSetを使用してください。

1

私はあなたがセットを使用するほうが良いことに同意します。配列を使用してセットを初期化することができます(例:var arrayOfModel:Set = [val1、val2、val3])。しかし、カスタムタイプを使用しているので、MyModelStructがハッシュ可能であることを確認する必要があります。 This link has a good explanation

しかし、あなたは、配列を使用する場合、あなたはあなたがSUBIDプロパティを持っているあなたの構造体を変更(および変数ではなくint型にする必要があり

let areEqual = rhs.id == lhs.id && rhs.subId == lhs.subId) 

let areEqual = rhs.id == lhs.id 

を変更する必要があります文字列の

あなたの質問に答えて、はい、あなたは配列上で反復する必要があります

+0

を行うことができます私はループする必要がありますように、また、どこかにこのプロパティを格納考えるには、配列を考えましたか? – user2206906

0

あなたはこの関数で配列の種類を拡張する場合:

extension Array 
    { 
    func uniqueValues<V:Equatable>(value:(Element)->V) -> [Element] 
    { 
     var result:[Element] = [] 
     for element in self 
     { 
      if !result.contains({ value($0) == value(element) }) 
      { result.append(element) } 
     } 
     return result 
    } 
    } 

あなたが使用して重複をクリーンアップすることができます:

var arrayCleaned = arrayOfModel.uniqueValues({$0.id!}) 

構造Equatableを作るために必要とせずに。

あなたの配列が非常に大きく、可能であれば、ソースであなたの配列への挿入をフィルタリングすることを検討したいかもしれませんが、これは効率的ではないことに注意してください。

+0

私はそれが非常に効率的で賢明で悪いとOPはこれは良いアイデアだと思うべきではないのでdownvoted – Kametrixom

+0

効率が悪い場合がありますが、唯一の答えかもしれません:) ありがとう – user2206906

3

私は本当に人々が答えを取ることを望んでいません。それが唯一のものなので、セットの力をどのように使うことができるのかがわかります。セットは、それが存在するかどうかにかかわらず、複数のセットを持つのが理にかなっていない場合に使用されます。セットは、要素がセット内にあるかどうか(contains)、要素を削除する(remove)、2つのセット(union)を組み合わせるかどうかをチェックするための高速メソッドを提供します。彼らはよく知っているので、多くの人が配列を必要とすることがよくありますが、しばしばセットは本当に必要なものです。

struct Model : Hashable { 
    var id : String? 

    var hashValue: Int { 
     return id?.hashValue ?? 0 
    } 
} 

func ==(l: Model, r: Model) -> Bool { 
    return l.id == r.id 
} 

let modelSet : Set = [ 
    Model(id: "a"), 
    Model(id: "hello"), 
    Model(id: "a"), 
    Model(id: "test") 
] 

// modelSet contains only the three unique Models 

セットにするために、種類の唯一の要件は、(Equatableを拡張)Hashableプロトコルです。ということで、ここでは、あなたがセットを使用する方法です。あなたの場合、ちょうどStringの基礎となるhashValueを返すことができます。あなたのIDが常に数値であれば、IntのタイプをIntに変更する必要があります。StringIntよりも効率が悪く、Stringを使用するのは意味がありません。

あなたは新しいモデルを受け取るたびに、あなただけの

modelSet.unionInPlace(newModels) 
関連する問題