2017-05-26 3 views
1

Ich habe ein Array von Modellobjekten, die ich aus JSON-Daten erstellt habe. Ich habe Tausende von Datensätzen, die Duplikate enthalten, die ich entfernen muss. Ein Datensatz wird als Duplikat betrachtet, wenn er denselben "Namen" und dieselben "Adressattribute" aufweist.Suchen nach Filtermethode zum Entfernen von doppelten Modellobjekten basierend auf zwei Attributen aus Array mit Swift

Das Problem ist, die einzige Möglichkeit, wie ich die doppelten Objekte entfernen kann, ist die Durchführung einer for-Schleife innerhalb einer for-Schleife-Suche, und ich frage mich, ob es keine bessere, effizientere Möglichkeit gibt? Ich denke, dass der beste Ansatz dafür wäre, die "Filter" -Methode zu verwenden, aber ich habe Schwierigkeiten bei der Konfiguration mit einem Array, das Modellobjekte mit mehreren Attributen enthält.

Mein Modell Objekt sieht wie folgt aus:

struct Person { 

    let id: Int 
    let name: String 
    let address: String 


    init(id:Int, name:String, address:String) { 
     self.id = id 
     self.name = name 
     self.address = address 
    } 
} 

Die Art und Weise Ich versuche, das Filtermethode auf meinem Array von Modellobjekten zu verwenden, sieht wie folgt aus (was ich weiß nicht funktioniert):

let uniqueArray = peopleArray.filter { $0.name == $1.name, $0.address == $1.address } 

Kann jemand sehen was ich falsch mache?

+0

Ich bekomme die Fehlermeldung, "Contextual Schließung Typ '(Person) -> Bool' erwartet ein Argument, aber zwei wurden in Schließung Körper verwendet. – syedfa

+0

Ich muss die Duplikate entfernen, die in der Sammlung existieren, so dass Meine gefilterte Sammlung enthält nur eindeutige Modellobjekte. Ich möchte nicht einfach nach einem Paar Namen und Adressen gleichzeitig suchen. – syedfa

+1

@syedfa, überprüfen Sie meine aktualisierte Antwort. –

Antwort

5

1: Sie benötigen eine Struktur zu gleichzusetzen Protokoll

func ==(lhs: Person, rhs: Person) -> Bool { 
    return lhs.name == rhs.name && lhs.address == rhs.address 
} 

2 entsprechen machen: Sie können einen Satz verwenden, um zu steuern, welche von Ihrem Array filtern Objekte, aber Sie müssen Ihre Struktur zu Hashable konform machen Protokoll, das eine hashValue-Eigenschaft hinzufügt.

struct Person: Equatable, Hashable { 
    let id: Int 
    let name: String 
    let address: String 
    init(id: Int, name: String, address: String) { 
     self.id = id 
     self.name = name 
     self.address = address 
    } 
    var hashValue: Int { 
     return name.hashValue^address.hashValue 
    } 
} 

3: Verwendung

let people = [Person(id: 1, name: "Name A", address: "Address A"), 
       Person(id: 2, name: "Name B", address: "Address B"), 
       Person(id: 2, name: "Name B", address: "Address B"), 
       Person(id: 3, name: "Name C", address: "Address C")] 

// Will keep the order 
var set: Set<Person> = [] 
let orderedset = people.filter{ set.insert($0).inserted } 
print(orderedset) 

// Will not keep the order 
let unique = Set<Person>(people) 
print(unique) 

Tipp:

Wenn die ID einzigartig ist, dass Sie es stattdessen für den Vergleich verwendet werden soll.

+3

Dies ist der Weg zu gehen.Sie können Schritt zu vereinfachen 3 though. Just like unique = Set (PeopleArray) wird es tun.Das Erstellen der Gruppe mit dem Array wird automatisch entfernen die Duplikate. – Nick

+0

@Nick, in der Tat. Ich habe diese Zeile aktualisiert. Vielen Dank. –

+1

Vielen Dank für Ihre Lösung! – syedfa

Verwandte Themen