Menu
Coddy logo textTech

Hashable

Teil des Abschnitts Objektorientierte Programmierung der Swift-Journey von Coddy. Lektion 40 von 57.

Hashable ermöglicht es, Werte in einem Set zu speichern oder als Schlüssel für ein Dictionary zu verwenden. Ein Hash ist eine aus dem Wert berechnete Zahl, die dazu dient, ihn schnell zu finden. Strukturen und Enumerationen, deren Eigenschaften alle Hashable sind, erhalten diese Konformität, indem sie sie deklarieren:

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)))

Ausgabe:

2
true

Hashable-Werte eignen sich gut als Schlüssel für Wörterbücher, zum Beispiel zum Zählen von Vorkommen strukturierter Werte:

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

Ausgabe:

2

Hashable baut auf Equatable auf. Wenn == nur einige Eigenschaften vergleicht, muss der Hash dieselben Eigenschaften verwenden, was in hash(into:) geschieht. Andernfalls könnten zwei gleiche Werte unterschiedliche Hashes erhalten, und ein Set würde beide behalten:

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)

Ausgabe:

2

Die Regel, die du dir merken solltest: Gleiche Werte müssen gleiche Hashes haben. Hashwerte ändern sich zwischen Programmläufen, daher solltest du sie niemals speichern oder ausgeben; verwende sie nur über Mengen und Wörterbücher.

// gleiche Werte -> gleiche Hashes (erforderlich)
// unterschiedliche Werte -> normalerweise unterschiedliche Hashes
func hash(into hasher: inout Hasher) {
    hasher.combine(id)          // genau die Eigenschaften, die == vergleicht
}
challenge icon

Aufgabe

Einfach

Ein Roboter auf einem Gitter bewegt sich von (0, 0) aus Schritt für Schritt um jeweils ein Feld in Richtung U, D, L oder R. Mache Position (x, y) Hashable und vervollständige explore(_:), das drei Zeilen zurückgibt: visited 5 cells (die Anzahl der unterschiedlichen Positionen einschließlich des Starts), revisits 2 (Bewegungen, die auf einem bereits besuchten Feld endeten) und most visited (0, 0) x3 (das Feld, das am häufigsten betreten wurde, wobei der Start als ein Besuch zählt; bei Gleichstand gewinnt das Feld, das diese Anzahl zuerst erreicht).

Der bereitgestellte Code liest eine Zeile mit Bewegungen ein und gibt jede zurückgegebene Zeile aus.

Dein Code gehört in Position.swift und Functions.swift. main.swift enthält den bereitgestellten Eingabe-/Ausgabecode und darf nicht bearbeitet werden.

Probier es selbst

// Gelieferter Ein-/Ausgabe-Code: belasse ihn wie er ist
var input: [String] = []
while let line = readLine() { input.append(line) }
for line in explore(input[0]) { print(line) }
quiz iconTeste dich selbst

Diese Lektion enthält ein kurzes Quiz. Starte die Lektion, um es zu beantworten und deinen Fortschritt zu speichern.

Alle Lektionen in Objektorientierte Programmierung

Übe selbstständig: Swift-Playground