¿Qué es un Map?
Entre las clases presentes en Flutter, una de las más difíciles de usar cuando se comienza probablemente sea el Map. Esta variable es una especie de lista en la que cada elemento se compone de dos entradas:
- Una clave (key);
- y un valor (value).
A diferencia de la clase List, que se representa entre corchetes [ ], el Map se coloca entre llaves { }. Por ejemplo, aquí tienes un ejemplo muy básico de un Map:
Map<dynamic, dynamic> mapNumeros = {"cero": 0, "uno": 1, "dos": 2};
Aquí, mis claves (keys) están representadas por los valores «cero», «uno» y «dos», y mis valores (values) por 0, 1 y 2.
Crear una variable de tipo Map en Flutter
Existen varias formas de crear un widget de tipo Map, ya sea manualmente o utilizando métodos.
Crear un Map manualmente
La forma más sencilla de crear un Map en Flutter es declararlo como una variable. Para ello, basta con declararlo y especificar los tipos de claves (keys) y valores (values) que aceptará. Por ejemplo, si quiero que mi Map tenga claves del tipo Int y valores del tipo String, lo declararé así:
Map<Int, String> miMapa = {};
Las parejas de clave-valor se colocan entre llaves y se separan por comas. Por ejemplo:
Map<Int, String> miMapa = {1: "Mi primer valor", 2: "Mi segundo valor", 3: "Mi tercer valor"};
Si no sabes de antemano qué tipo de claves o valores almacenará tu Map, o si serán de tipos diferentes, puedes usar el tipo dynamic, que permite almacenar cualquier tipo de valor.
Crear un Map a partir de un solo widget List
Flutter nos permite, gracias al método .fromIterable
, crear un Map a partir de un widget List que actúe como contador. Este método consta de 3 atributos:
- El número de iteraciones, definido por la lista que utilicemos;
- El valor key, al cual debemos asignar un valor;
- El valor value, que también deberá definirse.
Por ejemplo, aquí tienes un ejemplo muy simple tomado de la documentación de Flutter:
final numeros = <int>[1, 2, 3];
final mapa = Map<String, int>.fromIterable(numeros,
key: (item) => item.toString(),
value: (item) => item * item);
print(mapa);
↪ {1: 1, 2: 4, 3: 9}
En este caso, nuestras claves (keys) serán los valores contenidos en nuestra lista numeros. Los valores (values) serán los elementos de la lista multiplicados por sí mismos.
Si no asignas ningún valor a key o value, estos serán llenados automáticamente con los elementos de la lista. Por ejemplo:
final numeros = <int>[1, 2, 3];
final mapa = Map.fromIterable(numeros);
print(mapa);
↪ {1: 1, 2: 2, 3: 3}
Crear un Map a partir de dos widgets List
Flutter nos permite, gracias al método .fromIterables
, fusionar dos widgets de tipo List para crear un Map. Aquí tienes un ejemplo muy sencillo de cómo utilizarlo:
List<String> fundadores = ["Elon Musk", "Steve Jobs", "Jeff Bezos"];
List<String> empresas = ["Tesla", "Apple", "Amazon"];
Map<String, String> empresasFamosas = Map.fromIterables(fundadores, empresas);
print(empresasFamosas);
↪ {Elon Musk : Tesla, Steve Jobs : Apple, Jeff Bezos : Amazon}
Manipular los elementos de tu clase Map
Agregar un elemento a mi Map
Una o más nuevas parejas clave-valor pueden añadirse a un Map utilizando el método .addAll()
. Aquí tienes un ejemplo de cómo usarlo:
Map<int, String> numeros = {0: "cero", 1: "uno", 2: "dos"};
numeros.addAll({3: "tres", 4: "cuatro"});
print(numeros);
↪ {0: "cero", 1: "uno", 2: "dos", 3: "tres", 4: "cuatro"}
¿Qué tipos de variables pueden contenerse en un Map?
Los Maps pueden contener cualquier cosa, siempre que declares correctamente tu variable. Por ejemplo, pueden contener Strings
, Int
, Lists
, e incluso otros Maps
y widgets más complejos.
Eliminar un elemento de mi Map
Los elementos de un Map no se eliminan mediante el índice, como ocurre con las listas, sino mediante las claves. Para ello, puedes utilizar el método .remove()
, indicando la clave (key) del valor que deseas eliminar. Por ejemplo:
Map<String, int> numeros = {"cero": 0, "uno": 1, "dos": 2};
numeros.remove("uno");
print(numeros);
↪ {0: "cero", 2: "dos"}
El método .clear()
Otra manera de eliminar todos los elementos contenidos en tu Map es usando el método .clear()
. Esto eliminará todas las claves y valores del widget. Por ejemplo:
Map<String, int> numeros = {"cero": 0, "uno": 1, "dos": 2};
numeros.clear();
print(numeros);
↪ {}
Modificar un Map
Existen dos métodos para modificar los elementos ya existentes en tu Map.
Modificar un solo elemento
Para modificar un solo elemento de tu Map, Flutter pone a tu disposición el método .update()
. Este toma como parámetro la clave del valor que deseas cambiar y la nueva asignación que quieres darle. Por ejemplo:
Map<String, int> numeros = {"cero": 0, "uno": 3, "dos": 2};
numeros.update("uno", (valor) => 1);
print(numeros);
↪ {"cero": 0, "uno": 1, "dos": 2}
Además, puedes añadir un parámetro ifAbsent
, en caso de que la clave que quieres modificar no exista. Por ejemplo:
Map<String, int> numeros = {"cero": 0, "uno": 1, "dos": 2};
numeros.update("tres", (valor) => 3, ifAbsent: () => 3);
print(numeros);
↪ {"cero": 0, "uno": 1, "dos": 2, "tres": 3}
Modificar todo tu Map
Para modificar todos los elementos existentes en tu Map (por ejemplo, ponerlos en mayúsculas), Flutter ofrece el método .updateAll()
. Esto te permite modificar tanto las claves como los valores. Por ejemplo:
Map<String, int> numeros = {"cero": 0, "uno": 1, "dos": 2};
numeros.updateAll((clave, valor) => clave.toUpperCase());
print(numeros);
↪ {"CERO": 0, "UNO": 1, "DOS": 2}
Mostrar tu variable Map en la pantalla
Por supuesto, tus Maps no están hechas solo para almacenarse en variables, también pueden mostrarse en la pantalla. Para ello, deberás usar el widget ListView
con el método .builder()
y almacenar tus claves y valores en listas. Aquí te explico cómo hacerlo:
Map<dynamic, dynamic> mapNumeros = {"cero": 0, "uno": 1, "dos": 2};
List<String> listaClaves = mapNumeros.keys.toList();
List<String> listaValores = mapNumeros.values.toList();
Luego, puedes usar una de estas dos listas para construir tu ListView.builder()
y utilizar los elementos contenidos en ambas para tus ListTiles
. Para obtener más información sobre cómo mostrar tus listas en Flutter, te invito a consultar mi artículo sobre el widget ListView
en Flutter.
Otros métodos de Flutter relacionados con Maps
Aquí tienes otras funciones que puedes usar con tus widgets de tipo Map
.
containsKey()
Como su nombre indica, el método containsKey()
te permite verificar si una clave aparece o no en tu Map
, devolviendo un valor de tipo bool
. Así es como se usa:
Map<dynamic, dynamic> mapNumeros = {"cero": 0, "uno": 1, "dos": 2};
bool contieneCero = mapNumeros.containsKey("cero");
print(contieneCero);
↪ true
containsValue()
El método containsValue()
funciona de manera similar a containsKey()
, pero esta vez para los valores contenidos en el Map
:
Map<dynamic, dynamic> mapNumeros = {"cero": 0, "uno": 1, "dos": 2};
bool contieneTres = mapNumeros.containsValue(3);
print(contieneTres);
↪ false
removeWhere()
El método removeWhere()
te permite eliminar las claves o valores de tu Map
que cumplan una condición. Por ejemplo:
Map<dynamic, dynamic> mapNumeros = {"cero": 0, "uno": 1, "dos": 2};
mapNumeros.removeWhere((clave, valor) => clave.contains("e"));
print(mapNumeros);
↪ {"uno": 1}
forEach()
La función forEach()
te permite repetir una acción tantas veces como la longitud de tu Map
. Por ejemplo:
Map<dynamic, dynamic> mapNumeros = {"cero": 0, "uno": 1, "dos": 2};
mapNumeros.forEach((clave, valor) {
print(valor);
});
↪ 0
↪ 1
↪ 2
Conclusión
Ahora ya eres capaz de crear y manipular las variables más comunes que se ven en Flutter. Sin embargo, aún te quedan dos por aprender: DateTime
y URIs
: