2016-05-16 58 views
2

我想有兩個例臨牀枚舉與哈希的相關類型的每個符合哈希的,就像這樣:哈希的枚舉在斯威夫特

enum WordOrNumber { 
    case Word(String) 
    case Number(Int) 
} 

我對散列的第一個想法是以下幾點:

extension WordOrNumber: Hashable { 
    var hashValue: Int { 
     switch self { 
      case let .Word(word): 
       return word.hashValue & ~1 // ends in 0 
      case let .Number(number): 
       return number.hashValue | 1 // ends in 1 
     } 
    } 
} 

我不確定的是,這將如何與Swift的Dictionary和Set實現中的桶進行交互。

區分兩種情況是由LSB還是MSB,還是在中間的某個位置更好?

我認爲它沒有任何區別將hashValues左移1,然後加1,或者不,但我會很感興趣知道是否不是這種情況。

編輯: 我剛剛測試過它,它看起來像一個Int的hash值是它本身。這顯然是一個問題,因爲您經常會連續獲取整數,例如在枚舉Bla:Int {}中。所以我的新的和改進的(?)hash值是:

extension WordOrNumber: Hashable { 
    var hashValue: Int { 
     switch self { 
      case let .Word(word): // ends in 0 
       return word.hashValue << 1 
      case let .Number(number): // ends in 1 
       return number.hashValue << 1 &+ 1 
     } 
    } 
} 

以上關於LSB和MSB的問題依然存在。

+0

實際上沒有必要區分這兩種情況。你想達到什麼目的? – Sulthan

+0

我不確定你的意思?當然,String和hash的hashValues可能會有衝突,其中.Number(x)== .Word(y),這是有問題的? –

+0

爲什麼這會有問題?哈希函數並不意味着返回唯一的結果,真正重要的是等式的定義('Equatable',函數'==')。我還會假設'Set'和'Dictionary'都使用輔助哈希函數。 – Sulthan

回答

0

有類似:

extension WordOrNumber: Hashable { 
    var hashValue: Int { 
     switch self { 
     case .Word(let value): 
      return value.hashValue 
     case .Number(let value): 
      return value.hashValue 
     } 
    } 

    static func ==(lhs: WordOrNumber, rhs: WordOrNumber) -> Bool { 
     switch (lhs, rhs) { 
     case (.Word(let lhsValue), .Word(let rhsValue)): 
      return lhsValue == rhsValue 
     case (.Number(let lhsValue), .Number(let rhsValue)): 
      return lhsValue == rhsValue 
     default: 
      return false 
     } 
    } 
} 

...應該是足夠的。