我的词典的自定义hashable结构

时间:2016-06-19 07:42:50

标签: swift dictionary hashable

我想构建一个可用于我的字典键的hashable值。它应该由一个包含两个字符串和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.

1 个答案:

答案 0 :(得分:1)

问题不在于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是绝对的 时间点,表示为亚秒的浮点数 精度。