Menu
Coddy logo textTech

Hashable

Fait partie de la section Programmation orientée objet du Journey Swift de Coddy. Leçon 40 sur 57.

Hashable permet de stocker des valeurs dans un Set ou de les utiliser comme clés de Dictionary. Un hash est un nombre calculé à partir de la valeur, utilisé pour la retrouver rapidement. Les structures et les énumérations dont toutes les propriétés sont Hashable l’obtiennent en déclarant la conformité :

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

Sortie :

2
true

Les valeurs hachables constituent de bonnes clés de dictionnaire, par exemple pour compter les occurrences de valeurs structurées :

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

Sortie :

2

Hashable s’appuie sur Equatable. Lorsque == compare uniquement certaines propriétés, le hachage doit utiliser ces mêmes propriétés, ce qui est fait dans hash(into:). Sinon, deux valeurs égales pourraient obtenir des hachages différents et un ensemble conserverait les deux :

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)

Sortie :

2

La règle à retenir : les valeurs qui sont égales doivent avoir des hachages égaux. Les valeurs de hachage changent d’une exécution du programme à l’autre, alors ne les stockez ni ne les affichez jamais ; utilisez-les uniquement par l’intermédiaire des ensembles et des dictionnaires.

// valeurs égales -> hachages égaux (requis)
// valeurs différentes -> hachages généralement différents
func hash(into hasher: inout Hasher) {
    hasher.combine(id)          // exactement les propriétés que == compare
}
challenge icon

Défi

Facile

Un robot sur une grille se déplace de U, D, L, R d’une case à la fois à partir de (0, 0). Rendez Position (x, y) Hashable et complétez explore(_:), qui renvoie trois lignes : visited 5 cells (le nombre de positions distinctes, y compris le départ), revisits 2 (les déplacements qui aboutissent sur une case déjà visitée) et most visited (0, 0) x3 (la case visitée le plus grand nombre de fois, en comptant le départ comme une visite ; la première à atteindre ce nombre remporte les égalités).

Le code fourni lit une ligne de déplacements et affiche chaque ligne renvoyée.

Votre code doit être placé dans Position.swift et Functions.swift. main.swift contient le code fourni pour les entrées/sorties et ne peut pas être modifié.

Essayez vous-même

// Code d'entrée/sortie fourni : le laisser tel quel
var input: [String] = []
while let line = readLine() { input.append(line) }
for line in explore(input[0]) { print(line) }
quiz iconTestez-vous

Cette leçon comprend un petit quiz. Commencez la leçon pour y répondre et suivre votre progression.

Toutes les leçons de Programmation orientée objet

Entraînez-vous par vous-même : Playground Swift