Hashable
CoddyのSwiftジャーニー「オブジェクト指向プログラミング」セクションの一部。レッスン 40/57。
Hashable により、値を Set に格納したり、Dictionary のキーとして使用したりできます。ハッシュとは、値から計算される数値であり、その値をすばやく見つけるために使用されます。すべてのプロパティが Hashable である構造体や列挙型は、適合を宣言することでこれを取得できます。
struct Point: Hashable {
let x: Int, y: Int
}
var visited: Set<Point> = []
visited.insert(Point(x: 0, y: 0))
visited.insert(Point(x: 1, y: 0))
visited.insert(Point(x: 0, y: 0))
print(visited.count)
print(visited.contains(Point(x: 1, y: 0)))出力:
2
trueハッシュ可能な値は、構造化された値の出現回数を数える場合など、辞書のキーとして適しています。
struct Pair: Hashable {
let from: String, to: String
}
let trips = [Pair(from: "A", to: "B"), Pair(from: "B", to: "C"), Pair(from: "A", to: "B")]
var counts: [Pair: Int] = [:]
for t in trips { counts[t, default: 0] += 1 }
print(counts[Pair(from: "A", to: "B")]!)出力:
2Hashable は Equatable を基盤としています。== が一部のプロパティのみを比較する場合、ハッシュでも同じプロパティを使用する必要があり、それは hash(into:) で行います。そうしないと、等しい2つの値が異なるハッシュを持つ可能性があり、集合が両方を保持してしまいます。
struct User: Hashable {
let id: Int
var name: String
static func == (lhs: User, rhs: User) -> Bool { lhs.id == rhs.id }
func hash(into hasher: inout Hasher) { hasher.combine(id) }
}
let users: Set<User> = [User(id: 1, name: "Ada"), User(id: 1, name: "Ada L."), User(id: 2, name: "Bo")]
print(users.count)出力:
2覚えておくべきルール:等しい値は等しいハッシュ値を持たなければなりません。ハッシュ値はプログラムの実行ごとに変化するため、保存したり出力したりしてはいけません。セットや辞書を介してのみ使用してください。
// 等しい値 -> 等しいハッシュ(必須)
// 異なる値 -> 通常は異なるハッシュ
func hash(into hasher: inout Hasher) {
hasher.combine(id) // == が比較するプロパティとまったく同じ
}チャレンジ
簡単グリッド上のロボットが、(0, 0) から一度に1ステップずつ U、D、L、R に移動します。Position (x, y) を Hashable にし、3行を返す explore(_:) を完成させてください。返す3行は、visited 5 cells(開始位置を含む異なる位置の数)、revisits 2(すでに訪問したセルに着地した移動の数)、most visited (0, 0) x3(開始位置を1回の訪問として数え、最も多く入ったセル。同数の場合は、その回数に最初に到達したセルを選ぶ)です。
用意されたコードは移動を1行読み取り、返された各行を出力します。
コードは Position.swift と Functions.swift に記述します。main.swift には用意された入力/出力コードが含まれており、編集できません。
自分で試してみよう
// 提供された入出力コード: そのままにしておく
var input: [String] = []
while let line = readLine() { input.append(line) }
for line in explore(input[0]) { print(line) }
このレッスンには短いクイズがあります。レッスンを始めて解答し、進捗を記録しましょう。
オブジェクト指向プログラミングのすべてのレッスン
自分で練習してみよう: Swiftプレイグラウンド