Les dictionnaires sont des structures de données qui permettent de stocker et d'organiser des informations de manière associative. Chaque élément dans un dictionnaire est composé d'une clé et d'une valeur correspondante.

Ils permettent de stocker des données de manière efficace et de les récupérer rapidement en utilisant des clés uniques.

Dictionnaire

Pour déclarer un dictionnaire en Swift, on sépare les clés des valeurs par le symbole deux points (:). Les différentes clés et leurs valeurs associées sont séparées par des virgules (,) et le tout est encadré par des crochets ([ ]).


var monDictionnaire = [Cle1: Valeur1, Cle2: Valeur2, ...]

Dans un exemple plus concret, cela se traduirait par :


var fruits = ["pomme": 3, "banane": 5, "orange": 2]

Dans l'exemple ci-dessus, grâce à l'interférence de type, Swift en déduit qu'il s'agit d'un dictionnaire. La première clé se nomme pomme et a pour valeur 3, la seconde clé se nomme banane et a pour valeur 5 et enfin la troisième clé se nomme orange et a pour valeur 2.

Les clés doivent être toutes du même type et les valeurs toutes du même type.

Ce dictionnaire a des clés de type String et des valeurs de type Int. Ce dictionnaire est donc de type [String: Int].

Les clés d'un dictionnaire doivent toutes être du même type, et les valeurs doivent également être du même type. Cependant, le type des clés et le type des valeurs peuvent être différents.

Dictionnaire vide

Si on a besoin de déclarer un dictionnaire vide, on peut le faire soit explicitement par l'annotation de type, soit par l'interférence de type pour que Swift en déduise son type :


// Déclaration d'un dictionnaire vide

// Par annotation de type 
var dictionnaireVide: [String: Int] = [:]

// Par interférence de type
var autreDictionnaireVide = [String: Int]()

Dans les deux lignes de code ci-dessus, en premier nous déclarons le dictionnaire dictionnaireVide par annotation de type et ensuite le dictionnaire autreDictionnaireVide par interférence de type. Ces deux dictionnaires sont vides et ils sont tous les deux de type [String: Int].

En déclarant leur type, cela nous permet de sécuriser les futures entrées. Ces dictionnaires ne pourront recevoir que des clés de type String et des valeurs de type Int sinon cela provoquerait une erreur.

Comme les tableaux, les dictionnaires peuvent-être déclarés sous forme de constante ou de variable.

Itérer un dictionnaire

Beaucoup de notions vous paraitront plus simple aujourd'hui. Leurs fonctionnements sont très similaires aux tableaux que nous avons étudiés dans le chapitre précédent. À commencer par l'itération : pour parcourir un dictionnaire on utilise la boucle for.

Lors de l'itération, chaque élément du dictionnaire est renvoyé sous la forme d'un tuple. Vous pouvez décomposer les membres du tuple en tant que constantes utilisables uniquement depuis le corps de la boucle.


let nombrePatte = ["araignée": 8, "fourmi": 6, "chat": 4]

for (nom, nombre) in nombrePatte {
    print("\(nom) possède \(nombre) pattes")
}

// chat possède 4 pattes
// fourmi possède 6 pattes
// araignée possède 8 pattes

Le contenu d'un dictionnaire est intrinsèquement non ordonné, et, lors de son itération, rien ne garantit l'ordre dans lequel il sera récupéré. En particulier, l'ordre dans lequel vous insérez les éléments dans un dictionnaire ne définit pas l'ordre dans lequel ils sont itérés.

Il est possible également de ne parcourir que les clés ou que les valeurs d'un dictionnaire grâce aux propriétés keys et values :


let capitale = ["France": "Paris", "Belgique": "Bruxelles", "Suède": "Stockholm"]

for pays in capitale.keys {
    print("Quel est la capitale de la \(pays) ?")
}

// Quel est la capitale de la France ?
// Quel est la capitale de la Belgique ?
// Quel est la capitale de la Suède ?

for ville in capitale.values {
    print("\(ville) est la capitale de quel pays ?")
}

// Paris est la capitale de quel pays ?
// Bruxelles est la capitale de quel pays ?
// Stockholm est la capitale de quel pays ?

Lors de la première boucle, on parcourt l'ensemble des clés du dictionnaire. La seconde boucle est consacrée aux valeurs de ce dictionnaire.

Manipuler un dictionnaire

Compter le nombre d'éléments clé/valeur dans un dictionnaire

La méthode count permet de connaître le nombre d'éléments, paires clé-valeur, présents dans un dictionnaire. C'est un moyen simple de savoir combien d'éléments sont stockés dans votre dictionnaire à un moment donné.

Voici comment cela fonctionne :


let fruits = ["pomme": 3, "banane": 5, "orange": 2]

let nombreElements = fruits.count

print(nombreElements)
// Cela affichera : 3

Comme pour les tableaux, on applique la méthode count à un dictionnaire en indiquant le nom du dictionnaire suivi d'un point et du mot-clé count.

Vérifier si un dictionnaire est vide

Pour vérifier si un dictionnaire est vide, il préférable d'utiliser la méthode isEmpty plutôt que de passer par la méthode count et vérifier que celle-ci est égale à 0 :


let fruits = ["pomme": 3, "banane": 5, "orange": 2]

if fruits.isEmpty {
    // count = 0, dictionnaire vide
    print("Le dictionnaire est vide")
} else {
    print("Le dictionnaire contient un élément au minimum")
}
// Cela affiche : "Le dictionnaire contient un élément au minimum"

Ajouter une valeur à un dictionnaire

Pour ajouter un nouvel élément, on utilise un nouvelle fois la syntaxe d'indice. Vous remarquerez que c'est très pratique et que le code est plus lisible. Il suffit d'indiquer une nouvelle clé et de lui assigner une valeur :


let fruits = ["pomme": 3, "banane": 5, "orange": 2]

fruits["kiwi"] = 4 
// Ajoute 4 kiwis au dictionnaire

Attention, le type de la nouvelle clé doit être strictement identique au type de la clé du dictionnaire. Pareil pour les valeurs, la nouvelle doit être strictement du même type que celle du dictionnaire.

C'est dans l'utilisation des clés pour obtenir ou interagir sur les valeurs correspondantes que les différences entre les tableaux et les dictionnaires se remarquent le plus. Le coté plus pratique, plus rapide et plus lisible d'obtenir une valeur. Avec un dictionnaire, vous n'avez pas à vous soucier de son emplacement, juste de sa clé.

Modification d'une valeur d'un dictionnaire

Pour modifier la valeur associée à une clé, il vous suffit d'assigner une nouvelle valeur à cette clé. On utilise toujours la syntaxe des indices en indiquant la clé pour modifier la valeur correspondante :


let fruits = ["pomme": 3, "banane": 5, "orange": 2]

fruits["banane"] = 8 
// Maintenant, le nombre de bananes est 8

Accéder aux valeurs d'un dictionnaire

En Swift, on peut accéder à un élément d'un dictionnaire grâce à la syntaxe d'indice. On utilise une clé pour obtenir la valeur correspondante :


let fruits = ["pomme": 3, "banane": 5, "orange": 2]

let nombreDePommes = fruits["pomme"] 
// nombreDePommes contient maintenant la valeur 3

Malheureusement, tout n'est pas toujours aussi simple qu'on le voudrait. On utilise la syntaxe d'indice pour récupérer une valeur du dictionnaire pour une clé particulière, c'est vrai. Mais, comme il est possible de demander une clé pour laquelle aucune valeur n'existe, l'indice d'un dictionnaire renvoie une valeur optionnelle. Cette valeur est du même type que les autres valeurs du dictionnaire.

Les valeurs optionnelles sont un concept que nous découvrirons en fin de tutoriel. Mais pour faire simple et pour que vous puissiez avoir une idée de quoi il s'agit, une valeur optionnelle est une variable qui a une valeur ... ou pas. Si elle n'a pas de valeur, cela ne veut pas dire que c'est une chaine de caractères vide. Juste que sa valeur n'existe pas, on dit qu'elle vaut Nil.

Dans l'exemple ci-dessous, si le dictionnaire contient une valeur pour la clé demandée, alors l'indice renvoie une valeur optionnelle correspondante contenant la valeur existante pour cette clé. Elle est stockée dans une constante temporaire nommée fruit. Sinon, l'indice renvoie nil et la branche else est interprétée :


let fruits = ["pomme": 3, "banane": 5, "orange": 2]

if let fruit = fruits["pomme"] {
    print("Il en reste \(fruit)")
} else {
    print("Ce fruit n'est pas dans notre dictionnaire")
}
// Cela affichera : Il en reste 3

C'est une condition if un peu particulière. Nous reviendrons en détails sur celle-ci dans le chapitre sur le type optionnel. L'important à cet instant est que vous compreniez qu'on utilise la syntaxe d'indice en utilisant la clé pour accéder à une valeur correspondante.

Supprimer un élément du dictionnaire

La syntaxe d'indice étant omniprésente pour la manipulation d'un dictionnaire, nous l'utiliserons une nouvelle fois pour supprimer une paire clé/valeur. Il suffit juste d'attribuer la valeur nil à cette clé :


var fruits = ["pomme": 3, "banane": 5, "orange": 2]

fruits["banane"] = nil

print(fruits)
// Cela affichera : ["pomme": 3, "orange": 2]
En Swift, la valeur nil est utilisée pour représenter l'absence de valeur ou l'absence d'une référence à un objet. Elle est souvent utilisée pour initialiser des variables optionnelles lorsque vous ne voulez pas leur attribuer une valeur spécifique au départ.

On peut également utiliser la méthode removeValue(forKey:). On applique cette méthode au dictionnaire en indiquant, pour le paramètre nommé forKey:, la clé de l'élément à supprimer :


var fruits = ["pomme": 3, "banane": 5, "orange": 2]

fruits.removeValue(forKey: "banane")

print(fruits)
// Cela affichera : ["pomme": 3, "orange": 2]

Après les tableaux, vous êtes désormais capable d'utiliser des dictionnaires. Prenez toujours quelques instants pour regarder derrière vous et mesurer le parcours que vous avez déjà effectué. Soyez en fier. Vos capacités de futur développeur grandissent de jour en jour.

Dès le prochain chapitre, nous allons découvrir le dernier type de collection : Les ensembles.

  • Chaque élément dans un dictionnaire est composé d'une clé et d'une valeur correspondante.
  • Chaque clé est unique.
  • Les clés doivent être toutes du même type et les valeurs toutes du même type.
  • Lors de l'itération, rien ne garantit l'ordre dans lequel le dictionnaire sera récupéré.

Je vous conseille de faire chaque exercice de fin de chapitre. Cela consolidera votre apprentissage de manière efficace en passant de la théorie à la pratique. Faites vos propres experiences, n'ayez peur de rien, vous progresserez plus vite ainsi.

Pour cet exercice, nous partirons d'une base commune : le dictionnaire ci-dessous nommé personne. Il vous faudra ensuite filtrer toutes les personnes qui ont moins de 25 ans et les enregistrer dans un nouveau dictionnaire. Cela ne devrait pas vous poser de problème.


let personne = ["Jean": 65, "Ludivine": 12, "François": 71, "Michelle": 44, "Laura": 24]

  
let personne = ["Jean": 65, "Ludivine": 12, "François": 71, "Michelle": 44, "Laura": 24]

// On déclare un dictionnaire vide de type [String: Int]
var jeune: [String: Int] = [:]

// On filtre les personnes de moins de 25 ans 
// par une condition if lors de l'itération du dictionnaire.

for (nom, age) in personne {
    
    if age < 25 {
        // Si l'age est < 25 ans, on l'enregistre dans
        // un nouveau dictionnaire
        jeune[nom] = age
    }
    
}

print(jeune)

// Cela affichera :
// ["Laura": 24, "Ludivine": 12]