2015-07-10 25 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

聪明!出于某种原因没有考虑到这一点。 –

相关问题