Hashableとhash(into:)
DictionaryのキーやSetの要素として使えるようにします。
「Hashableとhash(into:)」はCoddyKit上の無料Swift Academyレッスンです。 これはレッスン2/4です。 下記で完全なレッスンを無料で読むことができます。その後、ブラウザ内の組み込みコードエディタと24時間対応のAIチューターでハンズオン演習できます。 これはSwift Academy学習パスの一部であり、ウェブとCoddyKitアプリ全体で進捗が同期されます。 Swift Academyコースには全4レッスンが含まれています。
Hashableとは
HashableはEquatableを拡張し、ハッシュ値を提供します。型をSetの要素やDictionaryのキーとして使用するには、Hashableへの準拠が必要です。
Hashableの自動生成
Equatableと同様に、Hashableのメンバーを持つ構造体と列挙型では、Hashableが自動生成されます。
struct Point: Hashable {
let x: Int
let y: Int
}
let set: Set<Point> = [Point(x: 0, y: 0), Point(x: 0, y: 0)]
print(set.count) // 1 -- duplicate collapsed型をDictionaryのキーとして使う
Hashableな型は、辞書のキーとして使用できます。
struct Coord: Hashable { let r: Int; let c: Int }
var grid: [Coord: String] = [:]
grid[Coord(r: 0, c: 0)] = "start"
print(grid[Coord(r: 0, c: 0)]!) // "start"Hashableの契約
等しい2つの値(==)は、必ず同じハッシュを生成しなければなりません。どちらかをカスタマイズする場合は、両方の整合性を保ってください。そうしないと、集合や辞書が正しく動作しなくなります。
カスタムhash(into:)
関連するプロパティをハッシャーに渡して、hash(into:)を実装します。
struct User: Hashable {
let id: Int
let name: String
func hash(into hasher: inout Hasher) {
hasher.combine(id)
}
static func == (l: User, r: User) -> Bool { l.id == r.id }
}
print(Set([User(id: 1, name: "A"), User(id: 1, name: "B")]).count) // 1複数のフィールドを組み合わせる
等価性の判定に関係するすべてのフィールドを渡します。
struct Pair: Hashable {
let a: Int
let b: String
func hash(into hasher: inout Hasher) {
hasher.combine(a)
hasher.combine(b)
}
}
print(Pair(a: 1, b: "x").hashValue == Pair(a: 1, b: "x").hashValue) // true識別に使うフィールドだけをハッシュする理由
==で使用するフィールドだけをハッシュしてください。追加の可変フィールドを含めると、「等しい値は同じハッシュになる」という規則に違反する可能性があります。
struct Doc: Hashable {
let id: Int // identity
var title: String // not part of equality
func hash(into hasher: inout Hasher) { hasher.combine(id) }
static func == (l: Doc, r: Doc) -> Bool { l.id == r.id }
}
print(Doc(id: 1, title: "v1") == Doc(id: 1, title: "v2")) // trueHashableな列挙型
列挙型は自動的にHashableになります。関連値がある場合は、関連値もHashableである必要があります。
enum Direction: Hashable { case north, south, east, west }
let visited: Set<Direction> = [.north, .north, .east]
print(visited.count) // 2Setによる重複排除
よくある用途の1つは、Setを経由して重複を削除することです。
let nums = [1, 2, 2, 3, 3, 3]
let unique = Array(Set(nums)).sorted()
print(unique) // [1, 2, 3]Hasherは実行ごとにランダム化される
ハッシュ値のシードはプログラムの実行ごとに設定されるため、hashValueをディスクに保存したり、起動をまたいで正確な数値に依存したりしないでください。
struct K: Hashable { let v: Int }
let h1 = K(v: 5).hashValue
// h1 is stable within this run only
print(K(v: 5) == K(v: 5)) // true -- equality is what to rely onDictionaryによるカウント
Hashableなキーは、頻度を数える処理を支えます。非常によく使われるパターンです。
let letters = ["a", "b", "a", "c", "b", "a"]
var counts: [String: Int] = [:]
for l in letters { counts[l, default: 0] += 1 }
print(counts["a"]!) // 3確認問題
hash(into:)は、==との関係でどの規則を守る必要がありますか。
まとめ
Hashableについて学びました。
HashableはEquatableを拡張し、Setの要素やDictionaryのキーに必要です- Hashableのメンバーを持つ構造体と列挙型では自動生成されます
- カスタム
hash(into:)では、==で使用する識別用フィールドだけを組み合わせます - 等しい値は同じハッシュにならなければならず、ハッシュは実行ごとにランダム化されます
次はComparableとソートです。
よくある質問
「Hashableとhash(into:)」レッスンは無料ですか?
はい。「Hashableとhash(into:)」の完全なテキストはこのウェブで無料で読めます。インタラクティブに演習し(組み込みコードエディタと24時間対応のAIチューター)、Swift Academyコースの残りをアンロックするには、CoddyKit PROにアップグレードしてください。 Swift Academyコースには全4レッスンが含まれています。
「Hashableとhash(into:)」で何を学びますか?
DictionaryのキーやSetの要素として使えるようにします。 ブラウザで直接実行するハンズオンコードでSwift Academyを演習し、24時間対応のAIチューターがレッスンを進める中での質問に答えます。
Swift Academyを始めるのに経験は必要ですか?
事前経験は必要ありません。CoddyKitのSwift Academyは初級者から上級者向けに構成されているため、ここから始めるか最初から始めて、自分のペースで進むことができます。 これはレッスン2/4です。
「Hashableとhash(into:)」レッスンにはどのくらい時間がかかりますか?
ほとんどのCoddyKitレッスンは約5~10分かかります。各レッスンはコンパクトでインタラクティブなので、着実に進歩し、ウェブとアプリ全体で正確に前回の場所から再開できます。
このSwift Academyレッスンでコードを書いて実行できますか?
はい。すべてのSwift Academyレッスンに組み込みコードエディタが含まれているため、ブラウザでリアルコードを書いて実行し、即座のAIフィードバックを取得できます。ローカル設定は不要です。
このコースのすべてのレッスン
- Equatableの自動合成
- Hashableとhash(into:)
- Comparableとソート
- カスタム等価性のセマンティクス