2015-07-10 22 views
6

我正在使用Swift構建一個項目,我試圖創建一個字典來存儲名爲Pixel(KEY,用於存儲RGB值等顏色信息)的自定義類的對象和int值(用於計算值相同顏色出現在同一圖像上多少次)。如何使用自定義類類型作爲Swift中Dictionary的鍵?

如果這是在C#中,工作代碼應該是:

Dictionary<Pixel, int> colorDictionary = new Dictionary< Pixel, int>();

在斯威夫特,我想:

var colorDictionary = Dictionary<Pixel, Int>() 

但是,錯誤我:

「類型 '像素' 不符合協議 '哈希的'」

我該怎麼做才能解決這個問題?非常感謝!

+0

問題由Andy Ibanez的提示解決。我也發現這個鏈接是有幫助的:http://www.swiftcoder.info/dev/codefellows/2014/8/2/how-to-implement-hashable-for-your-custom-class –

回答

3

要使用字典密鑰的任何自定義類型都必須符合Hashable協議。

該協議有一個必須實現的屬性。

var hashValue: Int { get }

使用該屬性生成詞典可用於查找原因,一個int。您應該嘗試使其生成的hashValue對每個像素都是唯一的。

雨燕該書有以下幾個音符,所以你也許可以做一個隨機哈希(只要它是唯一的):

跨越是同一個類型的hashValue屬性的返回值是不需要相同程序的不同執行或不同程序中的執行。

注意,因爲從 Hashable繼承,你還必須實現:

func ==(_ lhs: Self, _ rhs: Self) -> Bool. 

我不知道你的像素的內部結構是什麼,但你也許可以考慮兩個像素相等時都有相同的「x」和「y」值。最終的邏輯取決於你。

修改成你需要:

struct Pixel : Hashable { 

    // MARK: Hashable 
    var hashValue: Int { 
     get { 
      // Do some operations to generate a unique hash. 
     } 
    } 
} 

//MARK: Equatable 
func ==(lh: Pixel, rh: Pixel) -> Bool { 
    return lh.x == rh.x && rh.y == lh.y 
} 
+0

解釋和修改如下很有幫助!謝謝安迪!也感謝以下所有貢獻創意的人。 –

+0

Andy,我現在可以用Pixel類型聲明我想要的字典。但我不知道如何在Swift中使用 .contains(Key)。你能否提供一些提示?謝謝! –

+0

Dictionary的下標運算符返回一個可選項。如果返回的密鑰不爲零,只需檢查或選擇 - 解包。如果讓myVal = myDic [key] {...}。 –

1

落實哈希的協議是這樣的:

class Pixel : Hashable { 
    var alpha, red, green, blue : Int 

    init(red: Int, green: Int, blue: Int, alpha: Int) { 
     self.red = red 
     self.green = green 
     self.blue = blue 
     self.alpha = alpha 
    } 

    var hashValue : Int { 
     get { 
      return alpha^red^green^blue 
     } 
    } 
} 

func ==(lhs: Pixel, rhs: Pixel) -> Bool { 
    return lhs.alpha == rhs.alpha && lhs.red == rhs.red && lhs.green == rhs.green && lhs.blue == rhs.blue 
} 
3

繼續與什麼安迪伊瓦涅斯公佈。實現hashValue的捷徑是搭載String的hashValue。你可以做這樣的事情。

class Pixel: Hashable { 
    var r:Int = 0; 
    var g:Int = 0; 
    var b:Int = 0; 
    var a:Int = 0; 

    var hashValue: Int { 
     get { 
      return "\(r)\(g)\(b)\(a)".hashValue; 
     } 
    } 
} 

您還需要一個Equatable功能,因爲在這種情況下hashValues僅僅是用於驗證兩個對象進行快速檢查是不相等的。由於兩個對象可能具有相同的hash值,但不相等,所以您仍然需要實現==以像下面那樣定義相等性。

func ==(lhs: Pixel, rhs: Pixel) -> Bool{ 
    if lhs.r != rhs.r{ 
     return false; 
    } 
    if lhs.g != rhs.g{ 
     return false; 
    } 
    if lhs.b != rhs.b{ 
     return false; 
    } 
    if lhs.a != rhs.a{ 
     return false; 
    } 
    return true; 
} 
+1

聰明!出於某種原因沒有考慮到這一點。 –

相關問題