Hashable
Parte de la sección Programación orientada a objetos del Journey de Swift de Coddy. Lección 40 de 57.
Hashable permite almacenar valores en un Set o utilizarlos como claves de Dictionary. Un hash es un número calculado a partir del valor, que se utiliza para encontrarlo rápidamente. Las estructuras y enumeraciones cuyas propiedades son todas Hashable obtienen esta conformidad al declararla:
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)))Salida:
2
trueLos valores hashables son buenas claves de diccionario, por ejemplo, para contar las apariciones de valores estructurados:
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")]!)Salida:
2Hashable se basa en Equatable. Cuando == compara solo algunas propiedades, el hash debe usar las mismas propiedades, lo que se hace en hash(into:). De lo contrario, dos valores iguales podrían obtener hashes diferentes y un conjunto conservaría 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)Salida:
2La regla que debes recordar: los valores que son iguales deben tener hashes iguales. Los valores hash cambian entre ejecuciones del programa, así que nunca los almacenes ni los imprimas; úsalos únicamente mediante conjuntos y diccionarios.
// valores iguales -> hashes iguales (requerido)
// valores diferentes -> usualmente hashes diferentes
func hash(into hasher: inout Hasher) {
hasher.combine(id) // exactamente las propiedades que == compara
}Desafío
FácilUn robot en una cuadrícula se mueve U, D, L, R un paso a la vez desde (0, 0). Haz que Position (x, y) sea Hashable y completa explore(_:), que devuelve tres líneas: visited 5 cells (el número de posiciones distintas, incluida la inicial), revisits 2 (movimientos que terminaron en una celda ya visitada) y most visited (0, 0) x3 (la celda a la que se entró más veces, contando la posición inicial como una visita; la primera que alcanza ese número gana los empates).
El código proporcionado lee una línea de movimientos e imprime cada línea devuelta.
Tu código va en Position.swift y Functions.swift. main.swift contiene el código proporcionado de entrada/salida y no se puede editar.
Pruébalo tú mismo
// Código de entrada/salida suministrado: déjalo tal como está
var input: [String] = []
while let line = readLine() { input.append(line) }
for line in explore(input[0]) { print(line) }
Esta lección incluye un breve cuestionario. Empieza la lección para responderlo y registrar tu progreso.
Todas las lecciones de Programación orientada a objetos
1Clases y objetos
Trabajar con archivosDefinir clasesMétodos y selfInicializadoresLas clases son referenciasRepaso: tarjeta de biblioteca4Encapsulación
Control de accesoSolo lectura desde fueraProtección del estadoInicializadores que pueden fallarRepaso - Cuenta bancaria7Polimorfismo y genéricos
PolimorfismoConversión de tiposFunciones genéricasTipos genéricosRepaso - Calculadora de formas2Structs y tipos por valor
StructsSemántica de valoresMétodos mutablesStruct o claseRepaso - elemento del inventario5Herencia
SubclasesSobrescritura de métodosInicializadores y superfinal y jerarquíasRepaso: jerarquía de empleados8Protocolos estándar
CustomStringConvertibleEquatableComparableHashableRepaso - Ordenamiento personalizado11Proyecto: Gestión de bibliotecas
Libros y miembrosPréstamo de librosPractica por tu cuenta: Playground de Swift