Saltar a contenido

3.2 Mapas (diccionarios)

Un mapa (o diccionario) guarda pares clave → valor. En lugar de buscar por posición, como en una lista, se busca por clave: dado un nombre, su edad; dada una palabra, cuántas veces aparece. Las claves son únicas: si asignas otra vez la misma clave, se sobrescribe el valor.

En Kotlin Map<K, V> es de solo lectura (mapOf("Ana" to 25)) y MutableMap<K, V> es modificable (mutableMapOf). Conservan el orden de inserción.

Crear, consultar, modificar y borrar

fun main() {
    val edades = mutableMapOf("Ana" to 25, "Luis" to 30)
    println("edad de Ana: ${edades["Ana"]}")
    println("Pepe: ${edades["Pepe"] ?: "no está"}")
    println("Pepe con valor por defecto: ${edades.getOrDefault("Pepe", 0)}")

    edades["Eva"] = 22 // añadir
    edades["Ana"] = 26 // modificar
    for ((clave, valor) in edades) {
        println("$clave -> $valor")
    }
    edades.remove("Luis")
    println("tras borrar a Luis quedan ${edades.size}")

    val cuentas = mutableMapOf<String, Int>()
    for (palabra in "a b a c b a".split(" ")) {
        cuentas[palabra] = (cuentas[palabra] ?: 0) + 1
    }
    println("frecuencias:")
    for ((clave, valor) in cuentas) {
        println("$clave -> $valor")
    }
}

Salida:

edad de Ana: 25
Pepe: no está
Pepe con valor por defecto: 0
Ana -> 26
Luis -> 30
Eva -> 22
tras borrar a Luis quedan 2
frecuencias:
a -> 3
b -> 2
c -> 1
Operación En Kotlin
Consultar (null si no está) edades["Ana"]
Valor por defecto edades["Pepe"] ?: 0 · getOrDefault("Pepe", 0)
Añadir o modificar edades["Eva"] = 22
¿Existe la clave? "Ana" in edades · containsKey
Borrar edades.remove("Luis")
Tamaño edades.size
Solo claves · solo valores edades.keys · edades.values
Recorrer pares for ((clave, valor) in edades)

Consultar una clave que no existe

Consultar una clave que no existe no falla: devuelve null, y el tipo es Int?, así que el compilador te obliga a decidir qué hacer (?: 0, ?., un if).

Contar con un mapa

La segunda mitad del ejemplo es un patrón que se usa constantemente: contar cuántas veces aparece cada elemento. Para cada palabra, se lee su cuenta actual (o 0 si es la primera vez), se suma 1 y se guarda de nuevo.

Claves, valores y mapas de listas

fun main() {
    val notas = mapOf(
        "Ana" to listOf(7, 9),
        "Luis" to listOf(5, 6, 7),
    )
    println("claves: ${notas.keys.joinToString(", ")}")
    for ((nombre, lista) in notas) {
        var suma = 0
        for (n in lista) {
            suma += n
        }
        println("$nombre: media ${suma.toDouble() / lista.size}")
    }
    println("total de notas: ${notas.values.sumOf { it.size }}")
}

Salida:

claves: Ana, Luis
Ana: media 8.0
Luis: media 6.0
total de notas: 5

Los valores pueden ser de cualquier tipo, incluidas listas u otros mapas. Aquí cada alumno tiene una lista de notas; se recorre el mapa y, para cada par, se recorre su lista.

¿Mapa, lista o conjunto?

Necesito... Estructura
Datos ordenados a los que accedo por posición Lista
Buscar un dato a partir de otro (nombre → edad) Mapa
Saber si algo está, sin repeticiones Conjunto

Errores frecuentes

Error Cómo evitarlo
Usar el valor de una clave que no existe Comprueba, o usa el valor por defecto
Esperar un orden concreto Usa una versión ordenada si el orden importa
Modificar el mapa mientras lo recorres Recorre una copia de las claves o construye un mapa nuevo
Repetir una clave pensando que añade otra entrada Las claves son únicas: la segunda sobrescribe

Para practicar

Haz los ejercicios 3.2 de mapas. Y para ver cómo se escribe en otro lenguaje: Pasar de uno a otro.