====== dict ======
Manipule les dictionnaires
===== Syntaxe =====
dict append dictionaryVariable key ?string ...?
dict create ?key value ...?
dict exists dictionaryValue key ?key ...?
dict filter dictionaryValue filterType arg ?arg ...?
dict filter dictionaryValue key ?globPattern ...?
dict filter dictionaryValue script {keyVariable valueVariable} script
dict filter dictionaryValue value ?globPattern ...?
dict for {keyVariable valueVariable} dictionaryValue body
dict get dictionaryValue ?key ...?
dict incr dictionaryVariable key ?increment?
dict info dictionaryValue
dict keys dictionaryValue ?globPattern?
dict lappend dictionaryVariable key ?value ...?
dict map {keyVariable valueVariable} dictionaryValue body
dict merge ?dictionaryValue ...?
dict remove dictionaryValue ?key ...?
dict replace dictionaryValue ?key value ...?
dict set dictionaryVariable key ?key ...? value
dict size dictionaryValue
dict unset dictionaryVariable key ?key ...?
dict update dictionaryVariable key varName ?key varName ...? body
dict values dictionaryValue ?globPattern?
dict with dictionaryVariable ?key ...? body
===== Description =====
Cette commande permet de créer des dictionnaires, sortes de tableaux associatifs ([[:tcl:array]]) sans nom, mais avec des fonctionnalités supplémentaires.
==== append ====
dict append dictionaryVariable key ?string ...?
Cette opération ajoute la chaîne (ou les chaînes) donnée(s) à la valeur de la clé donnée dans la valeur du dictionnaire contenue dans la variable donnée, en écrivant la valeur du dictionnaire résultante dans cette variable. Les clés inexistantes sont traitées comme si elles correspondaient à une chaîne vide. La valeur mise à jour du dictionnaire est renvoyée.
==== create ====
dict create ?key value ...?
Renvoie un nouveau dictionnaire contenant chacune des correspondances clé/valeur énumérées en tant qu'arguments (clés et valeurs alternées, chaque clé étant suivie de la valeur qui lui est associée).
==== exists ====
dict exists dictionaryValue key ?key ...?
Cette fonction renvoie une valeur booléenne indiquant si la clé donnée (ou le chemin des clés à travers un ensemble de dictionnaires imbriqués) existe dans la valeur donnée du dictionnaire.
==== filter ====
dict filter dictionaryValue filterType arg ?arg ...?
Cette fonction prend une valeur de dictionnaire et renvoie un nouveau dictionnaire qui contient uniquement les paires clé/valeur qui correspondent au type de filtre spécifié (qui peut être abrégé.) Les types de filtres pris en charge sont les suivants:
* **dict filter //dictionaryValue// key //?globPattern ...?//** La règle des clés ne s'applique qu'aux paires clé/valeur dont les clés correspondent à l'un des motifs donnés (à la manière de [[:tcl:string#match|string match]]).
* **dict filter //dictionaryValue// script {//keyVariable valueVariable//} //script//** La règle de script teste la correspondance en affectant la clé à la variable clé et la valeur à la variable valeur, puis en évaluant le script donné, ce qui devrait donner une valeur booléenne (la paire clé/valeur n'étant incluse dans le résultat du filtre dict que lorsqu'une valeur vraie est renvoyée). Notez que le premier argument après le mot de sélection de la règle est une liste à deux éléments. Si le script renvoie une condition TCL_BREAK, aucune autre paire clé/valeur n'est prise en compte pour être incluse dans le dictionnaire résultant, et une condition TCL_CONTINUE équivaut à un résultat faux. Les paires clé/valeur sont testées dans l'ordre dans lequel les clés ont été insérées dans le dictionnaire.
* **dict filter //dictionaryValue// value //?globPattern ...?//** La règle de valeur ne s'applique qu'aux paires clé/valeur dont les valeurs correspondent à l'un des motifs donnés (à la manière de [[:tcl:string#match|string match]]).
==== for ====
dict for {keyVariable valueVariable} dictionaryValue body
Cette commande prend trois arguments, le premier étant une liste de noms de variables à deux éléments (pour la clé et la valeur respectivement de chaque correspondance dans le dictionnaire), le deuxième étant la valeur du dictionnaire à parcourir et le troisième étant un script à évaluer pour chaque correspondance avec les variables clé et valeur définies de manière appropriée (à la manière de [[:tcl:foreach]].) Le résultat de la commande est une chaîne vide. Si une évaluation du corps génère un résultat TCL_BREAK, aucune autre paire du dictionnaire ne sera itérée et la commande dict for se terminera immédiatement avec succès. Si une évaluation du corps génère un résultat TCL_CONTINUE, celui-ci sera traité exactement comme un résultat TCL_OK normal. L'ordre d'itération est l'ordre dans lequel les clés ont été insérées dans le dictionnaire.
==== get ====
dict get dictionaryValue ?key ...?
Étant donné une valeur de dictionnaire (premier argument) et une clé (deuxième argument), cette commande récupère la valeur de cette clé. Lorsque plusieurs clés sont fournies, la commande se comporte comme si le résultat de `dict get $dictVal $key` était transmis comme premier argument à `dict get`, les autres arguments étant les deuxièmes (et éventuellement les suivants). Cela facilite les recherches dans les dictionnaires imbriqués. Par exemple, les deux commandes suivantes sont équivalentes :
dict get $dict foo bar spong
dict get [dict get [dict get $dict foo] bar] spong
Si aucune clé n'est fournie, le `dict get` renverra une liste contenant des paires d'éléments de la même manière que pour [[:tcl:array#get|array get]]. En d'autres termes, le premier élément de chaque paire sera la clé et le second élément sera la valeur de cette clé.
Tenter de récupérer une valeur pour une clé qui n'est pas présente dans le dictionnaire est une erreur.
==== incr ====
dict incr dictionaryVariable key ?increment?
Cette opération ajoute la valeur d'incrémentation donnée (un entier qui prend par défaut la valeur 1 s'il n'est pas spécifié) à la valeur de la clé donnée dans la valeur du dictionnaire contenue dans la variable donnée, en réécrivant la valeur du dictionnaire résultante dans cette variable. Les clés inexistantes sont traitées comme si elles correspondaient à 0. C'est une erreur d'incrémenter une valeur pour une clé existante si cette valeur n'est pas un entier. La valeur mise à jour du dictionnaire est renvoyée.
==== info ====
dict info dictionaryValue
Cette fonction renvoie des informations (destinées à être affichées) sur le dictionnaire donné, bien que le format de ces données dépende de l'implémentation du dictionnaire. Pour les dictionnaires qui sont implémentés par des tables de hachage, on s'attend à ce que cette fonction renvoie la chaîne produite par Tcl_HashStats, comme pour [[:tcl:array#statistics]].
==== keys ====
dict keys dictionaryValue ?globPattern?
Renvoie une liste de toutes les clés de la valeur du dictionnaire donnée. Si un motif est fourni, seules les clés qui y correspondent (selon les règles de correspondance des chaînes) seront renvoyées. Les clés retournées seront dans l'ordre dans lequel elles ont été insérées dans le dictionnaire.
==== lappend ====
dict lappend dictionaryVariable key ?value ...?
Ajoute les éléments donnés à la valeur de la liste à laquelle la clé donnée correspond dans la valeur du dictionnaire contenue dans la variable donnée, en écrivant la valeur du dictionnaire résultante dans cette variable. Les clés non existantes sont traitées comme si elles correspondaient à une liste vide, et il est légal qu'il n'y ait pas d'éléments à ajouter à la liste. Le fait que la valeur associée à la clé ne soit pas représentable sous forme de liste constitue une erreur. La valeur mise à jour du dictionnaire est renvoyée.
==== map ====
dict map {keyVariable valueVariable} dictionaryValue body
Cette commande applique une transformation à chaque élément d'un dictionnaire et renvoie un nouveau dictionnaire. Elle prend trois arguments : le premier est une liste de noms de variables à deux éléments (pour la clé et la valeur respectivement de chaque correspondance dans le dictionnaire), le deuxième est la valeur du dictionnaire à parcourir, et le troisième est un script à évaluer pour chaque correspondance avec les variables clé et valeur définies de manière appropriée (à la manière de [[:tcl:lmap]]). Lors d'une itération où le script évalué se termine normalement (TCL_OK, par opposition à une erreur, etc.), le résultat du script est placé dans un dictionnaire accumulateur en utilisant la clé qui est le contenu actuel de la variable keyVariable à ce moment-là. Le résultat de la commande `dict map` est le dictionnaire accumulateur une fois que toutes les clés ont été parcourues.
Si l'évaluation du corps d'une étape particulière génère un [[:tcl:break]], aucune autre paire du dictionnaire ne sera itérée et la commande `dict map` se terminera immédiatement avec succès. Si l'évaluation du corps d'une étape particulière génère un [[:tcl:continue]], l'itération en cours est interrompue et le dictionnaire de l'accumulateur n'est pas modifié. L'ordre d'itération est l'ordre naturel du dictionnaire (typiquement l'ordre dans lequel les clés ont été ajoutées au dictionnaire ; l'ordre est le même que celui utilisé dans [[#for|dict for]]).
==== merge ====
dict merge ?dictionaryValue ...?
Renvoie un dictionnaire contenant le contenu de chacun des arguments dictionaryValue . Lorsque deux dictionnaires (ou plus) contiennent une correspondance pour la même clé, le dictionnaire résultant associe cette clé à la valeur selon le dernier dictionnaire de la ligne de commande contenant une correspondance pour cette clé.
==== remove ====
dict remove dictionaryValue ?key ...?
Renvoie un nouveau dictionnaire qui est une copie de l'ancien dictionnaire passé en premier argument, mais sans les correspondances pour chacune des clés énumérées. Il est autorisé qu'il n'y ait pas de clés à supprimer ou que les clés à supprimer ne soient pas présentes dans le dictionnaire d'entrée en premier lieu.
==== replace ====
dict replace dictionaryValue ?key value ...?
Renvoie un nouveau dictionnaire qui est une copie de l'ancien dictionnaire transmis en tant que premier argument, sauf que certaines valeurs sont différentes ou que des paires clé/valeur supplémentaires ont été ajoutées. Il est légal que cette commande soit appelée sans paires clé/valeur, mais illégal qu'elle soit appelée avec une clé mais pas de valeur.
==== set ====
dict set dictionaryVariable key ?key ...? value
Cette opération prend le nom d'une variable contenant une valeur de dictionnaire et place une valeur de dictionnaire mise à jour dans cette variable contenant une correspondance entre la clé donnée et la valeur donnée. Lorsque plusieurs clés sont présentes, cette opération crée ou met à jour une chaîne de dictionnaires imbriqués. La valeur mise à jour du dictionnaire est renvoyée.
==== size ====
dict size dictionaryValue
Renvoie le nombre de correspondances clé/valeur dans le dictionnaire donné.
==== unset ====
dict unset dictionaryVariable key ?key ...?
Cette opération (le compagnon de [[#set|dict set]]) prend le nom d'une variable contenant une valeur de dictionnaire et place dans cette variable une valeur de dictionnaire mise à jour qui ne contient pas de correspondance pour la clé donnée. Lorsque plusieurs clés sont présentes, cette opération décrit un chemin à travers les dictionnaires imbriqués jusqu'à la correspondance à supprimer. Au moins une clé doit être spécifiée, mais la dernière clé du chemin ne doit pas nécessairement exister. Tous les autres composants du chemin doivent exister. La valeur mise à jour du dictionnaire est renvoyée.
==== update ====
dict update dictionaryVariable key varName ?key varName ...? body
Exécute le script Tcl dans //body// avec la valeur de chaque clé (telle qu'elle a été trouvée en lisant la valeur du dictionnaire dans //dictionaryVariable//) mappée à la variable //varName//. Il peut y avoir plusieurs paires clé/NomVar. Si une clé n'a pas de correspondance, cela correspond à un nom de variable non défini. Lorsque body se termine, toute modification apportée aux varNames est répercutée dans le dictionnaire à l'intérieur de dictionaryVariable (à moins que dictionaryVariable ne devienne lui-même illisible, auquel cas toutes les mises à jour sont silencieusement rejetées), même si le résultat de body est une erreur ou un autre type de sortie exceptionnelle. Le résultat de la mise à jour du dict est (sauf erreur) le résultat de l'évaluation de body.
Chaque varName est mappé dans la portée entourant le dict update ; il est recommandé de n'utiliser cette commande que dans une portée locale (procédure, terme lambda pour [[:tcl:apply]], ou méthode). Pour cette raison, les variables définies par dict update continueront d'exister après la fin de la commande (à moins qu'elles ne soient explicitement [[#unset|désactivées]]). Notez que le mappage des valeurs vers les variables n'utilise pas de traces ; les modifications du contenu du dictionnaireVariable ne se produisent qu'à la fin de body.
==== values ====
dict values dictionaryValue ?globPattern?
Renvoie une liste de toutes les valeurs du dictionnaire donné. Si un motif est fourni, seules les valeurs qui y correspondent (selon les règles de correspondance des chaînes) seront renvoyées. Les valeurs retournées seront dans l'ordre dans lequel les clés associées à ces valeurs ont été insérées dans le dictionnaire.
==== with ====
dict with dictionaryVariable ?key ...? body
Exécute le script Tcl dans body avec la valeur de chaque clé dans dictionnaireVariable mappée (d'une manière similaire à dict update) à une variable portant le même nom. Lorsqu'une ou plusieurs clés sont disponibles, elles indiquent une chaîne de dictionnaires imbriqués, le dictionnaire le plus proche étant celui qui est ouvert pour l'exécution de body. Comme pour dict update, le fait de rendre dictionnaireVariable illisible entraînera le rejet des mises à jour du dictionnaire, ce qui se produit également si le contenu de dictionnaireVariable est modifié de manière à ce que la chaîne de dictionnaires n'existe plus. Le résultat de dict with est (sauf erreur) le résultat de l'évaluation de body.
Les variables sont mappées dans la portée entourant le dict with ; il est recommandé de n'utiliser cette commande que dans une portée locale (procédure, terme lambda pour apply, ou méthode). Pour cette raison, les variables définies par dict with continueront d'exister après la fin de la commande (à moins qu'elles ne soient explicitement désactivées). Notez que le mappage des valeurs vers les variables n'utilise pas de traces ; les modifications du contenu du dictionnaireVariable ne se produisent qu'à la fin de body.
Si la variable dictionnaire contient une valeur qui n'est pas un dictionnaire au moment où le corps se termine (ce qui peut facilement se produire si le nom est identique à l'une des clés du dictionnaire), une erreur se produit à ce moment-là. Il n'est donc pas recommandé d'utiliser cette commande lorsque les clés du dictionnaire sont susceptibles d'entrer en conflit avec le nom de la variable dictionnaire elle-même. Lorsque la clé contenue correspond à un dictionnaire, l'effet net est de combiner ce dictionnaire interne dans le dictionnaire externe.
===== Valeurs de dictionnaire =====
Les dictionnaires sont des valeurs qui contiennent une correspondance efficace, préservant l'ordre, entre des clés arbitraires et des valeurs arbitraires. Chaque clé du dictionnaire correspond à une seule valeur. Leur format textuel est exactement celui d'une liste comportant un nombre pair d'éléments, chaque correspondance dans le dictionnaire étant représentée par deux éléments dans la liste. Lorsqu'une commande prend un dictionnaire et en produit un nouveau sur la base de celui-ci (soit en le renvoyant, soit en l'écrivant dans la variable à partir de laquelle le dictionnaire de départ a été lu), le nouveau dictionnaire aura le même ordre de clés, modulo les clés supprimées et les nouvelles clés ajoutées à la fin. Lorsqu'une chaîne est interprétée comme un dictionnaire et qu'elle aurait autrement des clés en double, seule la dernière valeur d'une clé particulière est utilisée ; les autres sont ignorées, ce qui signifie que "pomme banane" et "pomme carotte pomme banane" sont des dictionnaires équivalents (avec des représentations de chaînes différentes).
Les opérations qui dérivent un nouveau dictionnaire à partir d'un ancien (par exemple, les mises à jour telles que [[#set|dict set]] et [[#unset|dict unset]]) préservent l'ordre des clés dans le dictionnaire. Les exceptions à cette règle concernent les nouvelles clés ajoutées, qui sont ajoutées à la séquence, et les clés supprimées, qui sont retirées de l'ordre.
===== Exemples =====
Création d'un dictionnaire :
set le_dico [dict create k1 v1 k2 v2 k3 v3]
Faute de dictionnaire, on aurait dû créer un tableau au moyen de la commande
array set le_tableau {k1 v1 k2 v2 k3 v3}
Récupération de la valeur "v2" associée à la clé "k2" :
puts [dict get $le_dico k2] ;# -> v2
Ajout de la clé k4 associée à la valeur v4 dans le dictionnaire :
dict set le_dico k4 v4 ;# k1 v1 k2 v2 k3 v3 k4 v4
Modification le la valeur associée à la clé k3 :
dict set le_dico k3 v3n ;# k1 v1 k2 v2 k3 v3n k4 v4
Suppression de la clé k2 (et de sa valeur associée)
dict unset le_dico k2 ;# k1 v1 k3 v3n k4 v4
Liste des clés
puts [dict keys $le_dico] ;# -> k1 k3 k4
puts [dict keys $le_dico *3] ;# -> k3
Une valeur-liste
dict lappend k5 v5 ;# k1 v1 k3 v3n k4 v4 k5 v5
dict lappend k5 v5a v5b ;# k1 v1 k3 v3n k4 v4 k5 {v5 v5a v5b}
Si une procédure doit accéder à un dictionnaire sans le modifier, on peut passer sa valeur. Avec un tableau, il faut toujours passer le nom :
proc get_val_dico {dico k} {return [dict get $dico $k]}
proc get_val_array {arrayName k} {upvar $arrayName array; return $array($k)}
puts [get_val_dico $le_dico k3] ;# -> v3n
puts [get_val_array le_tableau k3] ;# -> v3
===== Voir aussi =====
[[:tcl:array]]
{{tag>tcl}}