我的字典的自定义哈希结构
Custom hashable struct for my Dictionary
我想构建一个可散列值以用作我的字典的键。它应该由一个具有两个字符串和一个 NSDate 的结构组成。我不确定我是否在下面正确构建了 hashValue
getter:
// 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.
问题不在于您的 hashValue
实现,而是 ==
函数。
通常,x == y
意味着 x.hashValue == y.hashValue
,但 不是
另一种方式。不同的对象可以有相同的散列值。
甚至
var hashValue : Int { return 1234 }
是无效的,但 有效 哈希方法。
因此在 ==
中,您必须比较两个对象以获得准确的
平等:
func ==(lhs: ReminderNotificationValue, rhs: ReminderNotificationValue) -> Bool {
return lhs.notifiedReminderName == rhs.notifiedReminderName
&& lhs.notifiedCalendarTitle == rhs.notifiedCalendarTitle
&& lhs.notifiedReminderDueDate.compare(rhs.notifiedReminderDueDate) == .OrderedSame
}
你代码中的另一个问题是这两个调用
NSDate()
创建不同的日期,因为 NSDate
是绝对的
时间点,表示为具有亚秒级的浮点数
精度。
我想构建一个可散列值以用作我的字典的键。它应该由一个具有两个字符串和一个 NSDate 的结构组成。我不确定我是否在下面正确构建了 hashValue
getter:
// 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.
问题不在于您的 hashValue
实现,而是 ==
函数。
通常,x == y
意味着 x.hashValue == y.hashValue
,但 不是
另一种方式。不同的对象可以有相同的散列值。
甚至
var hashValue : Int { return 1234 }
是无效的,但 有效 哈希方法。
因此在 ==
中,您必须比较两个对象以获得准确的
平等:
func ==(lhs: ReminderNotificationValue, rhs: ReminderNotificationValue) -> Bool {
return lhs.notifiedReminderName == rhs.notifiedReminderName
&& lhs.notifiedCalendarTitle == rhs.notifiedCalendarTitle
&& lhs.notifiedReminderDueDate.compare(rhs.notifiedReminderDueDate) == .OrderedSame
}
你代码中的另一个问题是这两个调用
NSDate()
创建不同的日期,因为 NSDate
是绝对的
时间点,表示为具有亚秒级的浮点数
精度。