Les Maps : Introduction aux variables dans Flutter


Avatar de Pierre Courtois

Une classe de Flutter pouvant paraître impressionnant de prime abord est surement la Map. Comment créer une Map, y ajouter des éléments, les supprimer, etc ? J’essaye d’y répondre avec des exemples simples dans cet article.


Qu’est-ce qu’une Map ?

Parmi les classes présente dans Flutter, l’une des plus dures à utiliser quand on débute est probablement la Map. Cette variable est en quelque sorte une liste dont chaque item se compose de deux entrées par élément : 

  • Une valeur key (clé) ; 
  • et une value (valeur).

Contrairement à la class List qui est symbolisée par des crochets [ ], la Map est quant à elle mise entre deux accolades { }. Par exemple, voici un exemple très basique de Map : 

Map<dynamic, dynamic> mapChiffres = {"zero": 0, "un": 1, "deux": 2};

Ici, mes clés (keys) sont symbolisées par les valeurs zero, un et deux, et mes valeurs (values) par 0, 1 et 2. 

Quelle différence avec une liste ?

La liste ne comporte pas de clés, mais des index. Je ne peux donc pas leur assigner une valeur autre que int et que j’aurais moi-même définie. Ma liste va forcément commencer par l’index 0, puis 1, 2, etc.

Créer un Class Map dans Flutter

Il existe plusieurs manières de créer un widget de type Map, soit en le faisant vous-même, soit en utilisant des méthodes.

Créer une Map à la main 

La manière la plus simple de créer une Map sur Flutter est tout simplement de l’annoncer comme variable. Pour cela, il vous suffit de la déclarer et de préciser les keys et valeurs que celle-ci peut recevoir. Par exemple, si je souhaite que ma Map reçoive des clés des types Int, puis des valeurs de type String, je vais déclarer : 

Map<Int, String> myMap = { }

Les paires keys : value sont ensuite placées entre les accolades et séparées par des virgules. Par exemple : 

Map<Int, String> myMap = {1 : "Ma première valeur" , 2 : "Ma deuxième valeur", 3 : "Ma troisième valeur"}

Si vous ne savez pas à l’avance quel type de keys ou de valeurs seront stockés dans votre Map, ou que celles-ci seront différentes, vous pouvez utiliser le type dynamic. Celui-ci permet de stocker n’importe quel type de valeurs.  

Créer une Map à partir d’un seul widget List 

Flutter nous permet, grâce à la méthode .fromIterable, de créer une Map à partir d’un Widget List qui va nous servir de compte. Cette méthode se compose de 3 attributs : 

  • Le nombre d’itérations, qui va être défini par la liste que l’on va utiliser ; 
  • La valeur key, à laquelle on va devoir donner une valeur ; 
  • La valeur value, qui va aussi devoir être définie. 

Par exemple, voici l’exemple très simple qui est fourni dans la documentation de Flutter : 

final numbers = <int>[1, 2, 3];
final map = Map<String, int>.fromIterable(numbers,
    key: (item) => item.toString(),
    value: (item) => item * item);
print(map); 
↪ {1: 1, 2: 4, 3: 9}

Ici, nos keys vont être les valeurs qui sont contenues dans notre List numbers. Les values, quant à elle, seront les valeurs contenues dans la liste, multipliées par elles-mêmes.

Vous n’êtes bien-sûr pas obligé d’utiliser les éléments de votre liste pour créer vos keys et vos values. Ici, le widget List défini surtout le nombre d’itérations. 

Si vous ne donnez aucune valeur, ni à key, ni à value, alors celle-ci seront automatiquement remplies avec les éléments de la liste. Par exemple :

final numbers = <int>[1, 2, 3];
final map = Map.fromIterable(numbers);
print(map); 
↪ {1: 1, 2: 2, 3: 3}

Créer une Map à partir de deux widgets List 

Flutter nous permet, grâce à la méthode .fromIterables, de fusionner deux Widgets de type List, pour en faire une Map. Voici un exemple très simple de comment l’utiliser : 

List<String> fondateur = ["Elon Musk", "Steve Jobs", "Jeff Bezos"];
List<String> entreprise = ["Tesla", "Apple", "Amazon"];

Map<String, String> famousCompanies = Map.fromIterables(fondateur, entreprise); 
Print(famousCompanies) 

↪ {Elon Musk : Tesla, Steve Jobs : Apple, Jeff Bezos : Amazon}

Les listes que vous utilisez pour créer votre Map, doivent être du type annoncé dans la déclaration de la variable. Par exemple, si vous faites une map de type Map<String, int>, alors votre première liste doit contenir des chaînes de caractères et la deuxième, des chiffres.

Manipuler les items de votre Map

Ajouter un élément à ma Map

Une ou plusieurs nouvelles paires key : value, peuvent être ajoutées à une map en utilisant la méthode .addAll(). Voici un exemple de comment l’utiliser : 

Map<int, String> chiffres = {0: "zero", 1: "un", 2: "deux"}
chiffres.addAll({3 : "trois", 4: "quatre"})
print(chiffres) 

↪ {0: "zero", 1: "un", 2: "deux", 3 : "trois", 4: "quatre"}

Les paires que vous ajoutez à votre Map, doivent être du bon type, sans quoi vous recevrez un message d’erreur. The element type ‘xx’ can’t be assigned to the map key/value type ‘xx’.

Quels types de variables peuvent être contenues dans une Map ? 

Les Maps peuvent contenir n’importe quoi, dès lors que vous déclarez correctement votre variable. Par exemple, elle peut entre-autre contenir des Strings, des Int, des Lists, mais aussi d’autres Maps et Widgets plus complexes. 

Supprimer un élément de ma Map

Les éléments d’une Map ne se suppriment pas via l’index comme pour une liste, mais via les clés. Pour cela, vous pouvez utiliser la méthode .remove(), en indiquant la key de la valeur que vous souhaitez supprimer. Par exemple : 

Map<String, Int> chiffres = {"zero" : 0, "un" : 1, "deux" : 2}
chiffres.remove(“un”); 
print(chiffres); 

↪ {0: "zero", 2: "deux"}

Comment faire si je ne connais pas la clé que je veux supprimer, mais seulement son index ?

Si vous voulez supprimer une paire de votre Map, mais que vous ne connaissez pas la valeur de key, je vous conseille de créer une liste avec la méthode mapChiffres.keys.toList(). Vous pourrez ensuite retrouver la clé qui vous intéresse en utilisant cette fois-ci l’index et n’aurez plus qu’à utiliser la méthode .remove() avec celle-ci. 

La méthode clear() 

Une autre manière de supprimer tous les éléments contenus dans votre Map est d’utiliser la méthode .clear(). Celle-ci supprimera toutes les clés et les values contenues dans votre widget. Par exemple : 

Map<String, Int> chiffres = {"zero" : 0, "un" : 1, "deux" : 2}
chiffres.clear() 
print(chiffres)

↪ {}

Modifier une Map

Il existe deux méthodes permettant de modifier les éléments déjà existants, dans votre Map. 

Modifier un seul élément 

Pour modifier un seul élément de votre Map, Flutter met à disposition la méthode .update(). Celle-ci va prendre comme paramètre, la clé de la valeur que vous voulez modifier, puis la nouvelle valeur que vous voulez lui donner. Par exemple : 

Map<String, Int> chiffres = {"zero" : 0, "un" : 3, "deux" : 2}
chiffres.update("un", (value) => 1); 
print(chiffres)

↪ {"zero" : 0, "un" : 1, "deux" : 2}

De plus, vous pouvez aussi ajouter un paramètre ifAbsent, dans le cas où la clé à laquelle vous souhaitez accéder n’existe pas. Par exemple :

Map<String, Int> chiffres = {"zero" : 0, "un" : 1, "deux" : 2}
chiffres.update("trois", (value) => 3, ifAbsent: () => 3); 
print(chiffres)
↪ {"zero" : 0, "un" : 1, "deux" : 2, "trois" : 3}

Modifier toute votre map 

Pour modifier tous les éléments déjà existant dans votre Map (par exemple les mettre en majuscule), Flutter met à disposition la méthode .updateAll(). Celle-ci permet au choix de modifier vos keys, ou bien vos values. Par exemple : 

Map<String, Int> chiffres = {"zero" : 0, "un" : 1, "deux" : 2}
chiffres.updateAll((key, value) => key.toUpperCase()); 
print(chiffres)

↪ {"ZERO" : 0, "UN" : 1, "DEUX" : 2}

Afficher sa variable Map à l’écran

Bien-sûr, vos Maps ne sont pas faites que pour être stockées dans des variables et peuvent être affichées à l’écran. Vous devrez pour cela utiliser le widget Listview avec la méthode .builder() et stocker vos keys et vos values dans des listes. Pour cela, voici comment faire : 

Map<dynamic, dynamic> mapChiffres = {"zero": 0, "un": 1, "deux": 2};
List<String> keysLists = mapChiffres.keys.toList();
List<String> valuesLists = mapChiffres.values.toList();

Vous pouvez ensuite utiliser l’une de ces deux listes pour construire votre ListView.builder() et utiliser les éléments contenus dans les deux, pour vos ListTiles. Pour en savoir plus sur comment afficher vos listes dans Flutter, je vous invite à consulter mon article sur le widget ListView dans Flutter. 

Autres méthodes Flutter en lien avec les Maps

Voici d’autres méthodes que vous pouvez utiliser avec vos widgets de type de Map. 

containsKey()

Comme son nom l’indique, la méthode containsKey() vous permet de définir si une clé apparait ou pas dans votre Map, en renvoyant une valeur de type bool. Voici comment l’utiliser : 

Map<dynamic, dynamic> mapChiffres = {"zero": 0, "un": 1, "deux": 2};
String containsZero = mapChiffres.containsKey(“zero”); 
print(containsZero); 
true

containsValues()

La méthode containsValues() fonctionne comme la méthode containsKey() mais cette fois ci pour les valeurs contenues dans la Map : 

Map<dynamic, dynamic> mapChiffres = {"zero": 0, "un": 1, "deux": 2};
String containsThree = mapChiffres.containsValues(3); 
print(containsThree); 
false 

removeWhere()

La méthode removeWhere() vous permet de supprimer de votre Map les clés ou les valeurs qui répondent à une condition. Par exemple : 

Map<dynamic, dynamic> mapChiffres = {"zero": 0, "un": 1, "deux": 2};
mapChiffres.removeWhere((key, value) => key.contains(“e”)); 
print(mapChiffres); 

↪ {"un": 1};

forEach()

La fonction forEach vous permet de répeter une action un nombre de fois égal à la longueur de votre Map. Par exemple : 

Map<dynamic, dynamic> mapChiffres = {"zero": 0, "un": 1, "deux": 2};
mapChiffres.ofEach((key,value) {
print(value)
}); 

0
1
2

Conclusion

Vous êtes désormais capable de créer et manipuler les variables les plus couramment vues dans Flutter. Toutefois, il vous en reste encore deux à voir, les DateTime et les URIs :

Avatar de Pierre Courtois