Aller au contenu principal

Les tableaux et les collections

En C#, il existe deux types de structures de données qui permettent de stocker plusieurs valeurs dans une seule variable : les tableaux et les collections.

On différencie les tableaux des collections par leur capacité à être redimensionnés.

Un tableau a une taille fixe, il n'est pas possible de modifier la taille d'un tableau après sa création. Contraiement aux collections qui peuvent être redimensionnées.

Les tableaux

Les tableaux sont des structures de données qui permettent de stocker plusieurs valeurs dans une seule variable.

Pour définir un tableau, on utilise le mot clé new suivi du type des éléments du tableau et de la taille du tableau entre crochets [].

// Syntaxe :
(type)[] (name) = new (type)[(size)];

// Exemple :
int[] numbers = new int[5];
attention

Il n'est pas possible de modifier la taille d'un tableau après sa création.

Il est également possible d'initialiser un tableau avec des valeurs en utilisant des accolades {}.

int[] numbers = new int[] { 1, 2, 3, 4, 5 };
astuce

Il n'est pas nécessaire de spécifier la taille du tableau si vous initialisez le tableau avec des valeurs. Lorsque que vous initlialisez un tableau avec des valeurs, la taille du tableau est celle du nombre de valeurs que vous avez spécifié.

Si vous spécifiez la taille du tableau, vous devez également initialiser le tableau avec le même nombre de valeurs que la taille du tableau.

Accéder aux éléments d'un tableau

Pour accéder aux éléments d'un tableau, on utilise le nom du tableau suivi de l'index de l'élément entre crochets [].

int[] numbers = new int[] { 1, 2, 3, 4, 5 };

Console.WriteLine(numbers[0]); // Output: 1
Console.WriteLine(numbers[1]); // Output: 2
Console.WriteLine(numbers[4]); // Output: 5
// ...

Modifier les éléments d'un tableau

Pour modifier les éléments d'un tableau, on utilise le nom du tableau suivi de l'index de l'élément entre crochets [] et on affecte la nouvelle valeur à l'élément.

int[] numbers = new int[] { 1, 2, 3, 4, 5 };

numbers[0] = 10;
numbers[1] = 20;
numbers[2] = 30;
// ...

Parcourir un tableau

Pour parcourir un tableau, on utilise une boucle for et on utilise la propriété Length du tableau pour définir la condition de la boucle.

int[] numbers = new int[] { 1, 2, 3, 4, 5 };

for (int i = 0; i < numbers.Length; i++)
{
Console.WriteLine(numbers[i]);
}

Il est également possible de parcourir un tableau avec une boucle foreach vue dans le cours précédent.

int[] numbers = new int[] { 1, 2, 3, 4, 5 };

foreach (int number in numbers)
{
Console.WriteLine(number);
}

Les méthodes de la classe Array

Les tableaux sont des objets de type Array, cette classe contient plusieurs méthodes qui permettent de manipuler les tableaux.

Voici un résumé des méthodes les plus utilisées :

int[] arr = new int[] { 1, 2, 3, 4, 5 };

// Taille du tableau
Console.WriteLine(arr.Length); // Output: 5

// Index de la première occurence d'un élément
Console.WriteLine(Array.IndexOf(arr, 3)); // Output: 2

// Tri du tableau par ordre croissant
Array.Sort(arr); // arr = { 1, 2, 3, 4, 5 }

// Inversion de l'ordre des éléments du tableau
Array.Reverse(arr); // arr = { 5, 4, 3, 2, 1 }

// Copie du tableau
int[] copy = new int[5];
Array.Copy(arr, copy, 5); // copy = { 5, 4, 3, 2, 1 }

// Vider le tableau
Array.Clear(arr, 0, 5); // arr = { 0, 0, 0, 0, 0 }

Il existe d'autres méthodes dans la classe Array, vous pouvez les retrouver dans la documentation officielle.

Les collections

De la même manière que les tableaux, les collections sont des structures de données qui permettent de stocker plusieurs valeurs dans une seule variable, cependant celles-ci ont une taille variable.

Il existe plusieurs types de collections en C#, nous allons voir les plus utilisées.

Pour parcourir une collection, on utilisera les mêmes méthodes que pour les tableaux.

La collection List

Les listes sont le type de collection le plus couramment utilisé en C#. Elles sont similaires aux tableaux, mais elles peuvent être redimensionnées.

Elles ont pour avantage d'être plus flexibles que les tableaux, mais elles sont également moins performantes.

Pour définir une liste, on utilise le mot clé new suivi du type des éléments de la liste et des parenthèses ().

// Syntaxe :
List<(type)> (name) = new List<(type)>();
// Ou
List<(type)> (name) = new();

// Exemple :
List<int> numbers = new List<int>();
// Ou
List<int> numbers = new();
Inférence de type

Vous remarquerez qu'il est possible d'utiliser le mot clé new sans spécifier que l'on crée un objet de type List<T>. C'est ce que l'on appelle l'inférence de type.

Le compilateur sait que numbers est de type List<int> et donc il sait que l'on souhaite créer un objet de type List<int>, ici new() est donc équivalent à new List<int>().

Il est également possible d'initialiser une liste avec des valeurs en utilisant des accolades {}.

List<int> numbers = new() { 1, 2, 3, 4, 5 };

De la même manière que pour les tableaux, vous accédez aux éléments d'une liste en utilisant l'index de l'élément entre crochets [].

List<int> numbers = new() { 1, 2, 3, 4, 5 };

Console.WriteLine(numbers[2]); // Output: 3

Les méthodes de la classe List

La classe List<T> contient plusieurs méthodes qui permettent de manipuler les listes.

Voici un résumé des méthodes les plus utilisées :

List<int> numbers = new() { 1, 2, 3, 4, 5 };

// Taille de la liste
Console.WriteLine(numbers.Count); // Output: 5

// Ajouter un élément à la fin de la liste
// Add(element)
numbers.Add(6); // numbers = { 1, 2, 3, 4, 5, 6 }

// Ajouter un élément à une position spécifique
// Insert(index, element)
numbers.Insert(0, 0); // numbers = { 0, 1, 2, 3, 4, 5, 6 }

// Supprimer un élément
// Remove(element)
numbers.Remove(0); // numbers = { 1, 2, 3, 4, 5, 6 }

// Supprimer un élément à une position spécifique
// RemoveAt(index)
numbers.RemoveAt(0); // numbers = { 2, 3, 4, 5, 6 }

// Vider la liste
numbers.Clear(); // numbers = { }

La collection Dictionary

Les dictionnaires sont des collections qui permettent de stocker des paires clé-valeur.

Pour définir un dictionnaire, on utilise le mot clé new suivi du type de la clé et du type de la valeur entre chevrons <>.

// Syntaxe :
Dictionary<(keyType), (valueType)> (name) = new Dictionary<(keyType), (valueType)>();

// Exemple :
Dictionary<string, int> ages = new Dictionary<string, int>();

Il est également possible d'initialiser un dictionnaire avec des valeurs en utilisant des accolades {}.

Dictionary<string, int> ages = new()
{
{ "John", 20 },
{ "Jane", 25 },
{ "Jack", 30 }
};

Pour accéder aux valeurs d'un dictionnaire, on utilise la clé entre crochets [].

Dictionary<string, int> ages = new()
{
{ "John", 20 },
{ "Jane", 25 },
{ "Jack", 30 }
};

Console.WriteLine(ages["John"]); // Output: 20

Cas d'utilisation

Les dictionnaires sont très utiles pour stocker des données qui sont liées entre elles.

On les utilisera notamment pour :

  • Indexer des données : les dictionnaires sont souvent utilisés pour créer des index et accéder rapidement à des données.
  • Stocker des données de configuration : les dictionnaires sont souvent utilisés pour stocker des données de configuration, par exemple les paramètres d'une application.
  • Stocker des données de traduction : les dictionnaires sont souvent utilisés pour stocker des données de traduction, par exemple les traductions d'une application.

Les méthodes de la classe Dictionary

La classe Dictionary<TKey, TValue> contient plusieurs méthodes qui permettent de manipuler les dictionnaires.

Voici un résumé des méthodes les plus utilisées :

Dictionary<string, int> ages = new()
{
{ "John", 20 },
{ "Jane", 25 },
{ "Jack", 30 }
};

// Taille du dictionnaire
Console.WriteLine(ages.Count); // Output: 3

// Ajouter une paire clé-valeur
// Add(key, value)
ages.Add("Jill", 35); // ages = { "John": 20, "Jane": 25, "Jack": 30, "Jill": 35 }

// Supprimer une paire clé-valeur
// Remove(key)
ages.Remove("Jill"); // ages = { "John": 20, "Jane": 25, "Jack": 30 }

// Vider le dictionnaire
ages.Clear(); // ages = { }

La collection Queue

Les files sont des collections qui permettent de stocker des éléments dans un ordre précis. Les éléments sont ajoutés à la fin de la file et sont supprimés au début de la file, on parle de structure FIFO (First In - First Out).

Pour définir une file, on utilise le mot clé new suivi du type des éléments de la file entre chevrons <>.

// Syntaxe :
Queue<(type)> (name) = new Queue<(type)>();

// Exemple :
Queue<int> numbers = new Queue<int>();

Il est également possible d'initialiser une file avec des valeurs en utilisant des accolades {}.

Queue<int> numbers = new() { 1, 2, 3, 4, 5 };

Cas d'utilisation

Les files sont très utiles pour stocker des données qui doivent être traitées dans un ordre précis.

On les utilisera notamment pour :

  • Traiter des tâches : les files sont souvent utilisées pour traiter des tâches dans un ordre précis.

Les méthodes de la classe Queue

La classe Queue<T> contient plusieurs méthodes qui permettent de manipuler les files.

Voici un résumé des méthodes les plus utilisées :

Queue<int> numbers = new() { 1, 2, 3, 4, 5 };

// Taille de la file
Console.WriteLine(numbers.Count); // Output: 5

// Première valeur de la file
Console.WriteLine(numbers.Peek()); // Output: 1

// Ajouter un élément à la fin de la file
// Enqueue(element)
numbers.Enqueue(6); // numbers = { 1, 2, 3, 4, 5, 6 }

// Supprimer un élément au début de la file
// Dequeue()
numbers.Dequeue(); // numbers = { 2, 3, 4, 5, 6 }

// Vider la file
numbers.Clear(); // numbers = { }

La collection Stack

Les piles sont des collections qui permettent de stocker des éléments dans un ordre précis. Les éléments sont ajoutés au début de la pile et sont supprimés au début de la pile, on parle de structure LIFO (Last In - First Out).

Pour définir une pile, on utilise le mot clé new suivi du type des éléments de la pile entre chevrons <>.

// Syntaxe :
Stack<(type)> (name) = new Stack<(type)>();

// Exemple :
Stack<int> numbers = new Stack<int>();

Il est également possible d'initialiser une pile avec des valeurs en utilisant des accolades {}.

Stack<int> numbers = new() { 1, 2, 3, 4, 5 };

Cas d'utilisation

Les piles sont très utiles pour stocker des données qui doivent être traitées dans un ordre précis. On l'utilisera pour le même cas d'utilisation que les Queue, mais pour traiter des tâches dans l'ordre inverse de leur ajout.

Les méthodes de la classe Stack

La classe Stack<T> contient plusieurs méthodes qui permettent de manipuler les piles.

Voici un résumé des méthodes les plus utilisées :

Stack<int> numbers = new() { 1, 2, 3, 4, 5 };

// Taille de la pile
Console.WriteLine(numbers.Count); // Output: 5

// Première valeur de la pile
Console.WriteLine(numbers.Peek()); // Output: 5

// Ajouter un élément au début de la pile
// Push(element)
numbers.Push(6); // numbers = { 1, 2, 3, 4, 5, 6 }

// Supprimer un élément au début de la pile
// Pop()
numbers.Pop(); // numbers = { 1, 2, 3, 4, 5 }

// Vider la pile
numbers.Clear(); // numbers = { }

La collection HashSet

Les ensembles sont des collections qui permettent de stocker des éléments uniques. Les éléments sont stockés dans un ordre non précis.

Pour définir un ensemble, on utilise le mot clé new suivi du type des éléments de l'ensemble entre chevrons <>.

// Syntaxe :
HashSet<(type)> (name) = new HashSet<(type)>();

// Exemple :
HashSet<int> numbers = new HashSet<int>();

Il est également possible d'initialiser un ensemble avec des valeurs en utilisant des accolades {}.

HashSet<int> numbers = new() { 1, 2, 3, 4, 5 };

Cas d'utilisation

Les ensembles sont très utiles pour stocker des données qui doivent être uniques.

On les utilisera notamment pour :

  • Stocker des données uniques : les ensembles sont souvent utilisés pour stocker des données qui doivent être uniques, par exemple les emails d'une liste de diffusion.

Les méthodes de la classe HashSet

La classe HashSet<T> contient plusieurs méthodes qui permettent de manipuler les ensembles.

Voici un résumé des méthodes les plus utilisées :

HashSet<int> numbers = new() { 1, 2, 3, 4, 5 };

// Taille de l'ensemble
Console.WriteLine(numbers.Count); // Output: 5

// Ajouter un élément
// Add(element)
numbers.Add(6); // numbers = { 1, 2, 3, 4, 5, 6 }

// Supprimer un élément
// Remove(element)
numbers.Remove(6); // numbers = { 1, 2, 3, 4, 5 }

// Vider l'ensemble
numbers.Clear(); // numbers = { }