Menu
Coddy logo textTech

Hashable

Parte da seção Programação Orientada a Objetos do Journey de Swift da Coddy. Lição 40 de 57.

Hashable permite que valores sejam armazenados em um Set ou usados como chaves de um Dictionary. Um hash é um número calculado a partir do valor, usado para encontrá-lo rapidamente. Structs e enums cujas propriedades são todas Hashable obtêm essa conformidade ao declará-la:

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

Saída:

2
true

Valores hashable são boas chaves de dicionário, por exemplo, para contar ocorrências de valores estruturados:

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

Saída:

2

Hashable se baseia em Equatable. Quando == compara apenas algumas propriedades, o hash deve usar as mesmas propriedades, o que é feito em hash(into:). Caso contrário, dois valores iguais poderiam obter hashes diferentes, e um conjunto manteria ambos:

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)

Saída:

2

A regra a ser lembrada: valores iguais devem ter hashes iguais. Os valores de hash mudam entre as execuções do programa, portanto nunca os armazene nem os imprima; use-os somente por meio de conjuntos e dicionários.

// valores iguais -> hashes iguais (obrigatório)
// valores diferentes -> geralmente hashes diferentes
func hash(into hasher: inout Hasher) {
    hasher.combine(id)          // exatamente as propriedades que == compara
}
challenge icon

Desafio

Fácil

Um robô em uma grade se move U, D, L, R um passo de cada vez a partir de (0, 0). Torne Position (x, y) Hashable e complete explore(_:), que retorna três linhas: visited 5 cells (o número de posições distintas, incluindo o início), revisits 2 (movimentos que terminaram em uma célula já visitada) e most visited (0, 0) x3 (a célula acessada mais vezes, contando o início como uma visita; em caso de empate, vence a primeira a atingir essa contagem).

O código fornecido lê uma linha de movimentos e imprime cada linha retornada.

Seu código deve estar em Position.swift e Functions.swift. main.swift contém o código fornecido de entrada/saída e não pode ser editado.

REQUIRED OUTPUT FORMAT: [Your translated content here]

Experimente você mesmo

// Código de entrada/saída fornecido: mantenha-o como está
var input: [String] = []
while let line = readLine() { input.append(line) }
for line in explore(input[0]) { print(line) }
quiz iconTeste seus conhecimentos

Esta lição inclui um quiz rápido. Comece a lição para respondê-lo e acompanhar seu progresso.

Todas as lições de Programação Orientada a Objetos

Pratique por conta própria: Playground de Swift