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?
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)
}