All my life I believed, Set will replace the existing Value when inserting new Value to maintain it’s unique property. But today I am surprised that it’s not,
Code:
enum Action {
case edit
case delete
case update
}
struct Object: Equatable, Hashable {
let id: String
let action: Action
let code: UInt8
var description: String {
return "`\(self.action)` on `\(self.id)` with #\(self.code)"
}
init(id: String, action: Action, code: UInt8) {
self.id = id
self.action = action
self.code = code
}
func hash(into hasher: inout Hasher) {
hasher.combine(self.id)
}
static func == (lhs: Object, rhs: Object) -> Bool {
return lhs.id == rhs.id
}
}
So I used the property id to maintain unique. When I insert new object with same id and different other values then the Set is kept the old one instead of new insertion.
var collection = Set<Object>()
let obj1 = Object(id: "1", action: .delete, code: 1) // `delete` on `1` with #1
collection.insert(obj1)
let obj2 = Object(id: "1", action: .update, code: 4) // `update` on `1` with #4
collection.insert(obj2)
print(collection.first!.description) // `delete` on `1` with #1
The print supposed to be for code: 4 as I thought, but it is code: 1. Actually I did used the technique in a search-hungry project and lot of places and it’s not worked to be expected today, after long debug I did found this.
Is this the way Set works in Swift or Am I doing something wrong?
>Solution :
The issue there is that you are ignoring the result from the insert method. You should try to insert and if it is not inserted you can update the set. Something like:
if !collection.insert(obj2).inserted {
collection.update(with: obj2)
}