Reputation: 3868
I'd like to build a hashable value to be used for my dictionary's key. It should consist of a structure with two strings and an NSDate. I'm not sure I built my hashValue
getter correctly below:
// MARK: comparison function for conforming to Equatable protocol
func ==(lhs: ReminderNotificationValue, rhs: ReminderNotificationValue) -> Bool {
return lhs.hashValue == rhs.hashValue
}
struct ReminderNotificationValue : Hashable {
var notifiedReminderName: String
var notifiedCalendarTitle: String
var notifiedReminderDueDate: NSDate
var hashValue : Int {
get {
return notifiedReminderName.hashValue &+ notifiedCalendarTitle.hashValue &+ notifiedReminderDueDate.hashValue
}
}
init(notifiedReminderName: String, notifiedCalendarTitle: String, notifiedReminderDueDate: NSDate) {
self.notifiedReminderName = notifiedReminderName
self.notifiedCalendarTitle = notifiedCalendarTitle
self.notifiedReminderDueDate = notifiedReminderDueDate
}
}
var notifications: [ReminderNotificationValue : String] = [ : ]
let val1 = ReminderNotificationValue(notifiedReminderName: "name1", notifiedCalendarTitle: "title1", notifiedReminderDueDate: NSDate())
let val2 = ReminderNotificationValue(notifiedReminderName: "name1", notifiedCalendarTitle: "title1", notifiedReminderDueDate: NSDate())
notifications[val1] = "bla1"
notifications[val2] = "bla2"
notifications[val2] // returns "bla2".
notifications[val1] // returns "bla1". But I'd like the dictionary to overwrite the value for this to "bla2" since val1 and val2 should be of equal value.
Upvotes: 0
Views: 178
Reputation: 539745
The problem is not your hashValue
implementation, but the ==
function.
Generally, x == y
implies x.hashValue == y.hashValue
, but not
the other way around. Different objects can have the same hash value.
Even
var hashValue : Int { return 1234 }
would be an ineffective, but valid hash method.
Therefore in ==
, you have to compare the two objects for exact
equality:
func ==(lhs: ReminderNotificationValue, rhs: ReminderNotificationValue) -> Bool {
return lhs.notifiedReminderName == rhs.notifiedReminderName
&& lhs.notifiedCalendarTitle == rhs.notifiedCalendarTitle
&& lhs.notifiedReminderDueDate.compare(rhs.notifiedReminderDueDate) == .OrderedSame
}
Another problem in your code is that the two invocations
of NSDate()
create different dates, as NSDate
is an absolute
point in time, represented as a floating point number with sub-second
precision.
Upvotes: 1