1

I'm having some sets and I want to create the symmetricDifference:

class Message: NSObject, NSCopying {
    let id: String
    var content: String

    public init(id: String, content: String) {
        self.id = id
        self.content = content

        super.init()
    }

    override var hashValue: Int {
        return self.id.hashValue ^ self.content.hashValue
    }

    static func == (lhs: Message, rhs: Message) -> Bool {
        return lhs.id == rhs.id
    }

    override var description: String {
        return "ID: \(self.id) CONTENT: \(self.content)"
    }

    func copy(with zone: NSZone? = nil) -> Any {
        return Message(id: self.id, content: self.content)
    }
}

var originalMessages: Set<Message> = Set<Message>()

let message1 = Message(id: "12", content: "testje")
let message2 = Message(id: "13", content: "testje")
let message3 = Message(id: "14", content: "testje")

originalMessages.insert(message1)
originalMessages.insert(message2)
originalMessages.insert(message3)

print("Original messages")
print(originalMessages)

var newMessages: Set<Message> = Set<Message>()
let message4 = Message(id: "13", content: "testje")
let message5 = Message(id: "15", content: "testje")
newMessages.insert(message4)
newMessages.insert(message5)

print("New messages")
print(newMessages)

let newMessagesAndMessages = originalMessages.symmetricDifference(newMessages)

print("SymmetricDifference originalMessages and newMessages")
print(newMessagesAndMessages)

What I get is:

Original messages
[ID: 12 CONTENT: testje, ID: 14 CONTENT: testje, ID: 13 CONTENT: testje]
New messages
[ID: 15 CONTENT: testje, ID: 13 CONTENT: testje]
SymmetricDifference originalMessages and newMessages
[ID: 12 CONTENT: testje, ID: 13 CONTENT: testje, ID: 14 CONTENT: testje, ID: 15 CONTENT: testje, ID: 13 CONTENT: testje]

I would expect that the item 13 is only once in the set.

Why do I have the same item twice?

Martin R
  • 529,903
  • 94
  • 1,240
  • 1,382
user1007522
  • 7,858
  • 17
  • 69
  • 113
  • 2
    Possible duplicate of [NSObject subclass in Swift: hash vs hashValue, isEqual vs ==](https://stackoverflow.com/questions/33319959/nsobject-subclass-in-swift-hash-vs-hashvalue-isequal-vs) – Martin R Aug 14 '17 at 12:51
  • In an NSObject subclass you have to override `hash` and `isEqual` – Martin R Aug 14 '17 at 12:52
  • 1
    Note that equal objects *must* have the same hash value. With your implementation, two objects with the same id but different content are "equal", but have different hash values. – Martin R Aug 14 '17 at 12:55
  • 1
    [== overload for custom class is not always called](https://stackoverflow.com/q/42283715/2976878) may also be useful (specifically point #2) – Hamish Aug 14 '17 at 13:02

0 Answers0