我想使用一组自定义枚举作为字典键,但我很难弄清楚如何使阵列符合Hashable。编译器告诉我[符号]不符合Hashable。我需要做些什么才能编译?
我搞乱了Array的扩展,其中Element:Symbol,但我无法弄清楚如何以这种方式添加协议。
enum Symbol:Hashable, Equatable {
case Dot
case Dash
var value:Int {
get {
switch self {
case .Dot: return 0
case .Dash: return 1
}
}
var hashValue:Int {
return self.value
}
}
func ==(left: Symbol, right: Symbol) -> Bool {
return left.value == right.value
}
struct MorseDictionary {
static let symbolToStringDictionary:[[Symbol]:String] = [
[.Dot, .Dash]:"A"
]
}
答案 0 :(得分:3)
因此,您无法将Symbol
数组与Hashable
或Equatable
相符。
这意味着您不能在字典中使用符号数组作为键。
当然你可以创建一个扩展阵列(每个阵列!! )Equatable
和Hashable
,但这是一个疯狂的方法,因为很明显你永远不会能够提供有效的实施。
首先,你的枚举可以这样重写
enum Symbol: Int {
case Dot = 0, Dash
}
接下来,您需要一个Symbol
数组的包装器struct Symbols: Hashable, Equatable {
let value: [Symbol]
// you can use a better logic here
var hashValue: Int { return value.first?.hashValue ?? 0 }
}
func ==(left: Symbols, right:Symbols) -> Bool {
return !zip(left.value, right.value).contains { $0.0 != $0.1 }
}
现在您可以创建词典
let dict: [Symbols:String] = [Symbols(value: [.Dot, .Dash]) : "A"]
答案 1 :(得分:1)
我和@appzYourLife有同样的想法。所以不要接受我的回答。值得一提的是,我已经为Symbols实现了哈希函数。
func ==(left: Symbols, right: Symbols) -> Bool {
return left.value == right.value
}
enum Symbol: Int {
case Dot = 0
case Dash = 1
case Count = 2
}
struct Symbols: Hashable {
let symbols: [Symbol]
init(symbols: [Symbol]) {
self.symbols = symbols
}
var value: Int {
var sum = 0
var i = 1
symbols.forEach({ (s) in
sum += s.rawValue * i
i = i * Symbol.Count.rawValue
})
return sum
}
var hashValue: Int {
return value % Int(pow(Double(2), Double(Symbol.Count.rawValue)))
}
}
struct MorseDictionary {
static let symbolToStringDictionary: [Symbols: String] = [
Symbols(symbols: [.Dot, .Dash]): "A",
Symbols(symbols: [.Dash, .Dot]): "B",
Symbols(symbols: [.Dash, .Dash]): "C",
Symbols(symbols: [.Dot, .Dot]): "D",
]
}
客户代码:
MorseDictionary.symbolToStringDictionary[Symbols(symbols: [.Dot, .Dash])]
MorseDictionary.symbolToStringDictionary[Symbols(symbols: [.Dash, .Dot])]
MorseDictionary.symbolToStringDictionary[Symbols(symbols: [.Dash, .Dash])]
MorseDictionary.symbolToStringDictionary[Symbols(symbols: [.Dot, .Dot])]
结果:
"A"
"B"
"C"
"D"