将一系列枚举符合Hashable用作字典键

时间:2016-06-01 12:52:33

标签: ios arrays swift dictionary enums

我想使用一组自定义枚举作为字典键,但我很难弄清楚如何使阵列符合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"
    ]
}

2 个答案:

答案 0 :(得分:3)

在Swift 2.2中,您无法创建仅限于特定类型

的数组的扩展名

因此,您无法将Symbol数组与HashableEquatable相符。 这意味着您不能在字典中使用符号数组作为键。

当然你可以创建一个扩展阵列(每个阵列!! EquatableHashable,但这是一个疯狂的方法,因为很明显你永远不会能够提供有效的实施。

但是你可以采用另一种方法

首先,你的枚举可以这样重写

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"