/ /辞書キーとして使用するために列挙型の配列をHashableに適合させる-iOS、配列、Swift、辞書、列挙型

列挙型の配列をHashableに準拠させて辞書キーとして使用する - ios、配列、swift、辞書、列挙型

としてカスタム列挙型の配列を使用したいしかし、私は配列をHashableに適合させる方法を理解するのに苦労しています。コンパイラは[Symbol]がHashableに適合しないことを教えてくれます。これをコンパイルするには何をしなければなりませんか?

Element:SymbolというArrayの拡張機能をいじりましたが、そのようにプロトコルを追加する方法がわかりませんでした。

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"
]
}

回答:

回答№1の場合は3

Swift 2.2では、特定のタイプの配列に制限された拡張機能を作成できません

したがって、配列を適合させることはできません SymbolHashable または Equatable。 これは、辞書のキーとしてシンボルの配列を使用できないことを意味します。

もちろん、配列を作成する拡張機能を作成できます(すべての配列!!Equatable そして Hashable ただし、有効な実装を提供することは決してできないため、これはクレイジーなアプローチです。

ただし、別のアプローチに従うことができます

まず、列挙型をこのように書き換えることができます

enum Symbol: Int {
case Dot = 0, Dash
}

次に、シンボルの配列のラッパーが必要です

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"]

回答№2の場合は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"