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é |
|---|---|---|---|---|
|
|
|
|
- |
(tableau) |
/ |
|
- | - |
|
|
- | - | - |
|
, |
- | - | Possède un indexeur |
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 |
|---|---|---|---|---|
|
Oui | Oui | Oui () |
- |
(tableau) |
Oui (/boucle) |
Oui () |
Boucle | - |
|
Oui | - | Non (juste à la main) | - |
|
Oui () |
- | À 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).
GO TO FULL VERSION