CodeGym /Cours /C# SELF /Recherche d'éléments dans les collections en C#

Recherche d'éléments dans les collections en C#

C# SELF
Niveau 29 , Leçon 1
Disponible

1. Fonctions de base pour la recherche dans les collections

Souvent, les mots “recherche” et “filtrage” sont pris comme synonymes, mais en programmation, c'est pas tout à fait pareil.

  • Filtrage — c'est quand tu veux récupérer tous les éléments d'une collection qui remplissent une certaine condition (par exemple, tous les nombres supérieurs à 10).
  • Recherche — c'est quand tu veux généralement un seul élément : le premier qui convient, un élément avec une valeur précise, ou juste savoir s'il existe dans la collection.

Si on fait une analogie avec une bibliothèque : filtrer, c'est comme rassembler tous les livres sur le thème “Espace”, et chercher, c'est demander : “Vous avez le livre ‘Ulysse’ ?” ou “Où est le premier livre avec une couverture bleue ?”.

Toutes les collections principales de .NET (tableaux, listes, ensembles, dictionnaires, etc.) supportent plusieurs façons de chercher des éléments ou de vérifier leur présence.

Voyons les méthodes les plus courantes :

Collection Vérifier la présence Trouver l'index Trouver un élément Trouver par clé
List<T>
Contains
IndexOf
Find
-
T[]
(tableau)
Contains
/
Array.IndexOf
Array.IndexOf
- -
HashSet<T>
Contains
- - -
Dictionary<TKey,V>
ContainsKey
,
ContainsValue
- - Possède un indexeur
[key]

Certaines méthodes sont dispos que sur des types précis.

2. Recherche dans les listes : List<T>

List<T> — c'est une des collections les plus universelles pour stocker des éléments avec accès direct. Voici les méthodes de recherche principales :

Vérifier la présence d'un élément : Contains

Cette méthode te dit si l'élément voulu est dans la liste :

List<string> fruits = new List<string> { "Pomme", "Banane", "Kiwi" };
bool hasKiwi = fruits.Contains("Kiwi"); // true
bool hasMango = fruits.Contains("Mangue"); // false
Console.WriteLine(hasKiwi); // True

Sous le capot, Contains parcourt juste la collection en utilisant la méthode Equals.

Recherche d'index : IndexOf

Si tu veux savoir où se trouve exactement un élément (son numéro dans la liste) :

int index = fruits.IndexOf("Banane"); // 1 (indexation à partir de zéro)
int absentIndex = fruits.IndexOf("Pastèque"); // -1 (si l'élément n'existe pas)
Console.WriteLine(index);
Console.WriteLine(absentIndex);

Trouver le premier qui convient : Find

Tu peux chercher non pas par valeur exacte, mais par condition ! Pour ça, on utilise la méthode Find (ou sa cousine pour l'index — FindIndex) :

// Trouver le premier fruit dont le nom fait plus de 4 caractères
string longFruit = fruits.Find(fruit => fruit.Length > 4); // "Pomme"
Console.WriteLine(longFruit);

À noter : si rien n'est trouvé, ça renvoie la valeur par défaut du type (null pour les références).

Recherche de plusieurs éléments : FindAll

Si tu veux filtrer (tous ceux qui conviennent), utilise FindAll :

// Tous les fruits dont le nom contient la lettre 'i'
List<string> withI = fruits.FindAll(f => f.Contains('i'));
foreach (var fruit in withI)
    Console.WriteLine(fruit); // "Kiwi"

3. Recherche dans les tableaux : méthodes de la classe Array

Les tableaux n'ont pas de méthode Find à l'intérieur (comme List<T>), mais pour eux il y a la classe statique Array :

int[] numbers = { 1, 2, 3, 2, 4 };
int pos = Array.IndexOf(numbers, 2); // 1 — premier index du 2
int lastPos = Array.LastIndexOf(numbers, 2); // 3 — dernier index
Console.WriteLine(pos + ", " + lastPos);

Si tu veux trouver un élément selon une condition, tu peux utiliser une boucle simple :

int firstGreaterThanTwo = -1;
for (int i = 0; i < numbers.Length; i++)
{
    if (numbers[i] > 2)
    {
        firstGreaterThanTwo = numbers[i];
        break;
    }
}
Console.WriteLine(firstGreaterThanTwo); // 3

4. Méthodes universelles pour toutes les collections

Beaucoup de collections proposent des méthodes de recherche (genre Contains, IndexOf, Find etc). Si tu veux un truc plus compliqué, tu codes une boucle pour parcourir les éléments.

Exemple : Vérifier s'il y a un fruit qui commence par "B"

bool hasB = false;
foreach (var f in fruits)
{
    if (f.StartsWith("B"))
    {
        hasB = true;
        break;
    }
}
Console.WriteLine(hasB); // True

Exemple : Trouver le premier fruit qui contient "i"

string withI = null;
foreach (var f in fruits)
{
    if (f.Contains('i'))
    {
        withI = f;
        break;
    }
}
Console.WriteLine(withI); // "Kiwi"

Exemple : Recherche sur des objets personnalisés

class Student
{
    public string Name;
    public int Group;
    public int Id;
}

List<Student> students = new List<Student>
{
    new Student { Name = "Ivan", Group = 101, Id = 1 },
    new Student { Name = "Marie", Group = 101, Id = 2 },
    new Student { Name = "Pierre", Group = 102, Id = 3 },
};

// On cherche l'étudiant avec Id == 2
Student marie = null;
foreach (var s in students)
{
    if (s.Id == 2)
    {
        marie = s;
        break;
    }
}
if (marie != null)
    Console.WriteLine(marie.Name); // "Marie"
else
    Console.WriteLine("Étudiant non trouvé");

5. Recherche dans HashSet<T> : juste “Il y est ou pas ?”

Les ensembles (HashSet<T>) sont faits pour une recherche rapide “il y est ou pas”. Ils ne permettent pas de chercher par index, mais ils vérifient la présence super vite :

HashSet<int> set = new HashSet<int> { 1, 3, 5, 7 };
bool hasThree = set.Contains(3); // True
Console.WriteLine(hasThree);

// Si tu veux chercher selon une condition (genre, y a-t-il des nombres pairs) :
bool hasEven = false;
foreach (var x in set)
{
    if (x % 2 == 0)
    {
        hasEven = true;
        break;
    }
}
Console.WriteLine(hasEven); // False

6. Recherche dans les dictionnaires : Dictionary<TKey, TValue>

Le dictionnaire — c'est une collection de paires “clé-valeur”. La recherche par clé, c'est son super-pouvoir.

Vérifier la présence d'une clé

Dictionary<int, string> idToName = new Dictionary<int, string>
{
    { 1, "Vasya" }, { 2, "Katya" }
};
if (idToName.ContainsKey(2))
    Console.WriteLine(idToName[2]); // "Katya"

Recherche de valeur par clé : en toute sécurité !

if (idToName.TryGetValue(3, out string result))
    Console.WriteLine(result);
else
    Console.WriteLine("Pas d'étudiant avec cet Id"); // C'est ce qui s'affichera

Recherche par valeur (rare et lent) :

bool containsVasya = idToName.ContainsValue("Vasya");
Console.WriteLine(containsVasya); // True

Trouver une entrée selon une condition sur la valeur ou la clé

// Premier Id où le nom commence par "K"
KeyValuePair<int, string> entry = default;
bool found = false;
foreach (var pair in idToName)
{
    if (pair.Value.StartsWith("K"))
    {
        entry = pair;
        found = true;
        break;
    }
}
if (found)
    Console.WriteLine($"{entry.Key}: {entry.Value}"); // "2: Katya"

7. Astuces utiles

Tableau des méthodes de recherche

Type de collection Vérifier la présence Contains Trouver l'index IndexOf Trouver selon condition Find Recherche sûre par clé TryGetValue
List<T>
Oui Oui Oui (
Find
)
-
T[]
(tableau)
Oui (
Array.Contains
/boucle)
Oui (
Array.IndexOf
)
Boucle -
HashSet<T>
Oui - Non (juste à la main) -
Dictionary<TKey,V>
Oui (
ContainsKey
)
- À la main par clé/valeur Oui

Recherche itérative : on code à la main

Pour bien piger, essayons d'écrire nous-mêmes une méthode de recherche pour une collection. Par exemple, trouver l'index du premier élément supérieur à une valeur donnée :

static int FindFirstGreaterIndex(IEnumerable<int> collection, int minValue)
{
    int index = 0;
    foreach (var item in collection)
    {
        if (item > minValue)
            return index;
        index++;
    }
    return -1; // pas trouvé
}

var nums = new List<int> { 1, 4, 7, 2 };
Console.WriteLine(FindFirstGreaterIndex(nums, 3)); // 1 (nombre 4)

Ici, on n'est pas lié au type (List<T>, int[], même HashSet<T>), ni à l'implémentation interne.

Utilisation de la recherche dans des cas réels

  • Recherche d'utilisateur par login ou e-mail dans une base de données.
  • Vérifier si un produit est déjà dans le panier.
  • Recherche rapide de paramètres par nom.
  • Vérifier si une étape a déjà été faite (genre dans un workflow).
  • Trouver la position d'une erreur dans un tableau de logs.

La plupart des entretiens pour les devs middle incluent forcément la question : “Comment tu cherches des éléments dans une collection ? Comment tu écrirais une méthode qui retourne le premier/tous/l'index d'un élément selon une condition ?”. Donc s'entraîner à la recherche, c'est super utile !

8. Erreurs typiques et particularités de la recherche

Point important : les méthodes de recherche dépendent de la façon dont les objets sont comparés. Par exemple, si tu ajoutes tes propres classes dans une liste, la comparaison par défaut, c'est la comparaison de références ! Pour que la recherche marche “par contenu”, il faut redéfinir les méthodes Equals et GetHashCode (on verra ça plus en détail dans les prochaines leçons).

Exemple de problème :

var s1 = new Student { Name = "Egor", Id = 42 };
students.Add(s1);
// Maintenant on crée un nouvel objet avec le même Id et nom :
var s2 = new Student { Name = "Egor", Id = 42 };
Console.WriteLine(students.Contains(s2)); // False (!)

Le compilateur compare pas les champs, mais la référence (ce sont des objets différents).

Commentaires
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION