Los diccionarios son uno de los tipos de colección principales de Swift. Un diccionario almacena asociaciones sin orden entre claves únicas y sus valores correspondientes. Todas las claves de un diccionario deben ser del mismo tipo, y todos los valores también deben compartir el mismo tipo.
Los literales de diccionario se escriben como pares key: value separados por comas y encerrados entre corchetes ([]):
var addresses: Dictionary<String, String> = [
"The Munsters": "1313 Mockingbird Lane",
"The Simpsons": "742 Evergreen Terrace",
"Buffy Summers": "1630 Revello Drive"
]
var sequences: [String: [Int]] = [
"Euler's totient": [1, 1, 2, 2, 4, 2, 6, 4],
"Lazy caterer": [1, 2, 4, 7, 11, 16, 22, 29, 37],
"Carmichael": [561, 1105, 1729, 2465, 2821, 6601, 8911, 10585, 15841]
]
let constants = [
"pi": 3.14159,
"e": 2.71828,
"phi": 1.618033,
"avogadro": 6.02214076e23
]
Los tipos de diccionario se pueden escribir de forma explícita de dos maneras: Dictionary<Key, Value> o la sintaxis abreviada [Key: Value].
Para crear un diccionario vacío, especifica explícitamente sus tipos de clave y valor:
var emptyDict1: [Int: Int] = [:]
var emptyDict2 = [Character: String]()
var emptyDict3 = Dictionary<Int, Double>()
Puedes acceder a los valores con la notación de subíndice: coloca la clave entre corchetes ([]) después del nombre del diccionario.
Como puede que una clave no exista en el diccionario, el acceso por subíndice devuelve un opcional (Value?).
Si la clave está presente, Swift devuelve el valor envuelto; si no, devuelve nil:
let munster: String? = addresses["The Munsters"]
// Returns Optional("1313 Mockingbird Lane")
let carmichael = sequences["Carmichael"]
// Returns Optional([561, 1105, 1729, 2465, 2821, 6601, 8911, 10585, 15841])
let planck = constants["planck"]
// Returns nil
Para evitar trabajar con opcionales, puedes proporcionar un valor predeterminado con el parámetro default:
let e: Double = constants["e", default: 0]
// Returns 2.71828
let hoagie: [Int] = sequences["Hoagie", default: []]
// Returns []
let betty = addresses["Betty Cooper", default: "Address unknown"]
// Returns "Address unknown"
En los diccionarios mutables declarados con var, puedes agregar o actualizar pares clave-valor mediante asignación por subíndice:
sequences["Euler's totient"]?.append(contentsOf: [6, 4])
// sequences["Euler's totient"] is now [1, 1, 2, 2, 4, 2, 6, 4, 6, 4]
addresses["Betty Cooper"] = "111 Queens Ave."
addresses["Betty Cooper", default: "Address unknown"]
// Returns "111 Queens Ave."
constants["Gelfond's"] = 23.140692
// Compiler error: Cannot assign through subscript: 'constants' is a 'let' constant
Puedes recorrer cada par clave-valor de un diccionario con un bucle for-in.
Cada elemento se entrega como una tupla (key, value):
for (name, address) in addresses {
print("\(name) lives at \(address)")
}
Como los diccionarios no tienen orden, al ordenarlos se produce un array de pares clave-valor.
Puedes pasar un closure al método sorted(by:) que compara dos tuplas (key, value) y devuelve true si la primera tupla debe aparecer antes que la segunda:
func sortByNameLengthThenValue(_ lhs: (key: String, value: Double), _ rhs: (key: String, value: Double)) -> Bool {
let left = lhs.value + Double(lhs.key.count)
let right = rhs.value + Double(rhs.key.count)
return left < right
}
let sortedConstants = constants.sorted(by: sortByNameLengthThenValue)
En este ejercicio, vas a implementar una forma de llevar un registro de los puntajes altos del juego más popular de la sala de arcade de tu zona.
Tienes 7 funciones por implementar, todas relacionadas con devolver y manipular un diccionario de datos de puntajes altos.
Crea una función newScoreBoard() que no reciba parámetros y devuelva un nuevo diccionario de puntajes altos cuyas claves sean de tipo String y cuyos valores sean de tipo Int.
Para agregar un jugador al diccionario de puntajes altos, define addPlayer(_:_:_:), una función que recibe 3 parámetros:
var highScores = newScoreBoard()
addPlayer(&highScores, "Dave Thomas")
// Returns ["Dave Thomas": 0]
addPlayer(&highScores, "José Valim", 486_373)
// Returns ["Dave Thomas": 0, "José Valim": 486_373]
Para eliminar a un jugador del diccionario de puntajes altos, define removePlayer(_:_:), que recibe 2 parámetros:
Esta función debe eliminar al jugador del diccionario si está en él y no hacer nada en caso contrario.
var highScores = ["Dave Thomas": 0, "José Valim": 486_373]
removePlayer(&highScores, "Dave Thomas")
// Returns ["José Valim": 486_373]
removePlayer(&highScores, "Rose Fanaras")
// Returns ["José Valim": 486_373]
Para restablecer el puntaje de un jugador, define resetPlayer(_:_:), que recibe 2 parámetros:
La función establece en 0 el puntaje del jugador. Si el jugador no está en el diccionario, no debe pasar nada.
var highScores = ["Dave Thomas": 486_373, "José Valim": 10]
resetScore(&highScores, "Dave Thomas")
// Returns ["Dave Thomas": 0, "José Valim": 10]
Para actualizar el puntaje de un jugador sumando al puntaje anterior, define updateScore, que recibe 3 parámetros:
var highScores = ["Dave Thomas": 0, "José Valim": 486_373]
addPlayer(&highScores, "Freyja Ćirić", 12_771_008)
updateScore(&highScores, "Freyja Ćirić", 73)
// Returns ["Dave Thomas": 0, "José Valim": 486_373, "Freyja Ćirić": 12_771_081]
Define la función orderByPlayers, que recibe 1 parámetro:
La función devuelve un array de tuplas (String, Int) que son los jugadores y sus puntajes altos, ordenado de forma ascendente por el nombre del jugador.
var highScores = ["Dave Thomas": 0, "José Valim": 486_373, "Freyja Ćirić": 12_771_091]
orderByPlayers(highScores)
// Returns [("Dave Thomas", 0), ("Freyja Ćirić", 12_771_091), ("José Valim", 486_373)]
Para obtener una lista de jugadores ordenada por puntaje en orden descendente, define orderByScores, que recibe 1 parámetro:
La función devuelve un array de tuplas (String, Int) que son los jugadores y sus puntajes altos, ordenado de forma descendente por el puntaje del jugador.
var highScores = ["Dave Thomas": 0, "José Valim": 486_373, "Freyja Ćirić": 12_771_091]
orderByScores(highScores)
// Returns [("Freyja Ćirić", 12_771_091), ("José Valim", 486_373), ("Dave Thomas", 0)]
Regístrate en Exercism para aprender y dominar Swift con 35 conceptos116 ejercicios y mentoría humana real, todo gratis.