MG32 MG32 - 20 days ago 6
Swift Question

Find and remove duplicate items in a custom array type

I have the following class, based on a node/key combo:

class cellData {
let nodeText : String
let keyText : String

init(nodeText: String, keyText: String) {
self.nodeText = nodeText
self.keyText = keyText
}

var desription: String { return "<Node; name: \(nodeText); key; \(keyText)>" }
}


Based on the class above, I created two sets:

var firstSetData = [cellData]()
var secondSetData = [cellData]()

firstSetData = [cellData(nodeText: "a", keyText: "1"),
cellData(nodeText: "a", keyText: "2"),
cellData(nodeText: "c", keyText: "42")]

secondSetData = [cellData(nodeText: "a", keyText: "1"),
cellData(nodeText: "b", keyText: "100"),
cellData(nodeText: "c", keyText: "2"),
cellData(nodeText: "d", keyText: "1")]


I need a function that will return a 3rd set of class "cellData", but with only one unique instance of the same node/key combo. That means my final set has to look like this:

finalSet = [cellData(nodeText: "a", keyText: "1"),
cellData(nodeText: "a", keyText: "2"),
cellData(nodeText: "b", keyText: "100"),
cellData(nodeText: "c", keyText: "2"),
cellData(nodeText: "c", keyText: "42")]
cellData(nodeText: "d", keyText: "1")]


I tried something like this, but it doesn't quite work:

for node in combinedSetData {
if (combinedSetData.filter({$0.nodeText == node.nodeText && $0.keyText == node.keyText})).count > 1 {
// remove duplicate elements and append to new set
}

}


Swift 3 would be preferred if possible. Thank you in advance!

Answer

First, make your cellData class conforms to Equatable:

class cellData : Equatable { 
   static func ==(lhs: cellData, rhs: cellData) -> Bool {
        return lhs.nodeText == rhs.nodeText && lhs.keyText == rhs.keyText
    }

    // ...
}

Then building your finalSetData is easy:

var finalSetData = [cellData]()
(firstSetData + secondSetData).forEach {
    if !finalSetData.contains($0) {
        finalSetData.append($0)
    }
}

// To match the order in your example...
finalSetData.sort {
    if $0.nodeText != $1.nodeText {
        return $0.nodeText < $1.nodeText
    } else {
        return $0.keyText < $1.keyText
    }
}

A few other points:

  • desription is misspelled
  • You better conform the class to CustomStringConvertible too
  • Follow Swift's naming convention. You will thank yourself later. Rename your class to CellData