CodeGym /Cours /C# SELF /Fonctions d’agrégation : Sum, Count, Average, Max, M...

Fonctions d’agrégation : Sum, Count, Average, Max, Min

C# SELF
Niveau 32, Leçon 1
Disponible

1. Intro

Quand tu bosses avec des collections, souvent t’as pas juste envie de boucler sur chaque élément, mais plutôt d’avoir un petit “résumé” sur tout le jeu de données. Genre :

  • Compter combien d’étudiants ont eu la note maximale.
  • Savoir combien il y a d’élèves dans l’école.
  • Calculer la somme des points obtenus par tous les étudiants à l’exam.
  • Trouver la note la plus haute et la plus basse.
  • Calculer la moyenne de la classe.

Bien sûr, tout ça tu pourrais le faire avec une boucle classique et un compteur. Mais franchement, qui a envie d’écrire vingt lignes de code pour un truc aussi basique ?

LINQ te file tout un set de fonctions d’agrégation — des méthodes prêtes à l’emploi qui prennent ta collection, la parcourent et te sortent la réponse : somme, moyenne, max, min, et parfois des trucs plus malins.

Petit “tableau des agrégats” :

Méthode Ce qu’elle fait Retourne
Count()
Compte le nombre d’éléments
int
Sum()
Fait la somme des valeurs numériques Dépend du type des éléments (
int
,
double
, ...)
Average()
Calcule la moyenne arithmétique
double
ou un autre type numérique
Max()
Choppe l’élément le plus grand Un élément de la collection
Min()
Choppe l’élément le plus petit Un élément de la collection

Toutes ces méthodes sont des extension-methods pour les collections qui implémentent IEnumerable<T>. Plus de détails — doc officielle LINQ sur les méthodes d’agrégation.

2. Préparer les données pour la pratique

On va continuer avec une appli simple pour gérer des étudiants. Imaginons qu’on a cette classe :


// Modèle étudiant
public class Student
{
    public string Name { get; set; }
    public int Grade { get; set; } // Note sur 5
    public string Email { get; set; }
}

Et une liste :


// Liste de base des étudiants
List<Student> students = new List<Student>
{
    new Student { Name = "Ivan", Grade = 5, Email = "ivan@example.com" },
    new Student { Name = "Olga", Grade = 4, Email = "olga@example.com" },
    new Student { Name = "Artem", Grade = 3, Email = "artem@example.com" },
    new Student { Name = "Darya", Grade = 5, Email = "darya@example.com" },
    new Student { Name = "Petr", Grade = 2, Email = "petr@example.com" }
};

3. Compter les éléments : Count()

Stat de base

Par exemple, tu veux savoir combien t’as d’étudiants :


int totalStudents = students.Count(); // 5
Console.WriteLine($"Nombre total d’étudiants : {totalStudents}");

LINQ-magic : Easy ! La méthode Count() te retourne le nombre d’éléments dans la collection.

Compter avec une condition

Et combien de cracks dans la classe ?


int excellentStudents = students.Count(s => s.Grade == 5);
Console.WriteLine($"Nombre d’étudiants avec la note maximale : {excellentStudents}");

Ici, on passe à Count une lambda — elle va juste prendre ceux qui matchent la condition (s.Grade == 5). En interne, c’est comme Where(...).Count(), mais c’est plus court et un poil plus rapide.

Et si la collection est vide ?

Si la collection est vide, Count te retourne 0 — pas d’erreur.

4. Faire la somme : Sum()

Choper la somme de toutes les notes

Imaginons que tu veux la somme totale des points du groupe :


int sumOfGrades = students.Sum(s => s.Grade); // 5+4+3+5+2 = 19
Console.WriteLine($"Somme de toutes les notes : {sumOfGrades}");

Sum prend un sélecteur (lambda) qui retourne la valeur pour chaque élément.

Somme sur une collection de nombres

Si t’as juste une liste de nombres, pas besoin de sélecteur :


int[] numbers = { 1, 2, 3, 4, 5 };
int sum = numbers.Sum(); // 15

Erreurs classiques et subtilités

Si la collection est vide, Sum() pour les types numériques retourne 0. Mais si c’est une collection de types nullable (int?, double?), Sum gère aussi : il ignore les null.

5. Moyenne arithmétique : Average()

Calculer la moyenne de la classe

Classique : quelle est la moyenne des étudiants ?


double averageGrade = students.Average(s => s.Grade); // (5+4+3+5+2)/5 = 3.8
Console.WriteLine($"Moyenne de la classe : {averageGrade:F2}");

Average — super utile pour les stats. À noter : le retour est toujours un double, même si les valeurs de base étaient des int. Comme ça, pas de perte de décimales.

Si y’a aucun élément

Si la collection est vide, Average() balance une exception InvalidOperationException. C’est un piège classique : si t’es pas sûr qu’il y a des éléments, check avant !


if (students.Any())
    Console.WriteLine(students.Average(s => s.Grade));
else
    Console.WriteLine("Pas de données pour calculer la moyenne !");

Moyenne sur un tableau de nombres


double avg = numbers.Average();

6. Max et min : Max() et Min()

Qui est la star de la classe, et qui est au fond ?

Tu veux savoir qui cartonne et qui galère ? Facile :


int maxGrade = students.Max(s => s.Grade); // 5
int minGrade = students.Min(s => s.Grade); // 2

Console.WriteLine($"Note maximale : {maxGrade}");
Console.WriteLine($"Note minimale : {minGrade}");

Mais c’est qui ce héros ?

Parfois, tu veux pas juste la note, mais le nom du boss. On chope l’étudiant avec la meilleure note :


// On prend le premier après tri décroissant
var bestStudent = students.OrderByDescending(s => s.Grade).First();
Console.WriteLine($"Meilleur étudiant : {bestStudent.Name} ({bestStudent.Grade})");

Dans les versions récentes de .NET, y’a aussi MaxBy pour faire ça plus proprement. Depuis .NET 6 c’est dispo, et .NET 9 a encore amélioré le truc (voir MaxBy sur Microsoft Docs). Mais même sans MaxBy, le tri + .First() marche nickel.

Pièges et différences

Si la collection est vide, Max() et Min() balancent aussi une InvalidOperationException. Donc, sois prêt (surtout si t’as pas checké la collection avant) :


if (students.Any())
    Console.WriteLine($"Note maximale : {students.Max(s => s.Grade)}");
else
    Console.WriteLine("Pas d’étudiants pour chercher le max.");

7. Exemples de “chaînes” de méthodes d’agrégation

Souvent, tu combines les méthodes d’agrégation avec des filtres et des projections :


// Moyenne parmi les cracks
double avgExcellent = students
    .Where(s => s.Grade == 5)
    .Average(s => s.Grade); // toujours 5, mais c’est pour l’exemple

// Somme des notes pour ceux qui ont au moins 4
int sumGood = students
    .Where(s => s.Grade >= 4)
    .Sum(s => s.Grade);

// Nombre d’emails uniques (au cas où)
int uniqueEmails = students
    .Select(s => s.Email)
    .Distinct()
    .Count();

C’est là que LINQ devient vraiment cool : tu combines les opérations et t’as un code expressif et lisible, même ton chat pourrait piger (bon, si ton chat est Junior C# Dev).

8. Comparaison avec la méthode “à la main” : pourquoi utiliser les agrégats ?

Pour bien piger, comparons LINQ avec une boucle classique pour calculer la moyenne :

Méthode classique :


int sum = 0;
int count = 0;
foreach (var s in students)
{
    sum += s.Grade;
    count++;
}
double average = (count != 0) ? (double)sum / count : 0;

LINQ :


double average = students.Average(s => s.Grade);

Même pour gérer une collection vide, c’est plus simple !

9. Détails utiles

Petit mot sur la perf et l’implémentation

Les agrégats LINQ, contrairement à la plupart des opérations LINQ, s’exécutent directement ! Donc, quand tu appelles Sum(), Count(), Average(), Max(), Min(), tout le parcours de la collection se fait à ce moment-là. Ces méthodes te retournent pas une collection, mais un résultat unique.

C’est super important : si t’as fait un truc lourd avant l’agrégat, genre un gros filtre ou une transformation — ça s’exécute qu’une seule fois, au moment de l’agrégat.

Les méthodes d’agrégation supportent-elles le query-syntax ?

Souvent, les débutants demandent : “On peut écrire tout ça en query-syntax ?” Réponse courte : le query-syntax n’a pas de mots-clés pour les agrégats, mais tu peux toujours mixer avec la method syntax :


var avg = (from s in students where s.Grade > 3 select s.Grade).Average();

Dans les parenthèses — du query-syntax classique, puis tu appelles la méthode d’agrégation. On fait ça plus souvent qu’on croit !

10. Erreurs classiques avec LINQ

Erreur n°1 : essayer d’utiliser Average(), Max() ou Min() sur une collection vide.
Si la collection est vide, Sum() et Count() te retournent tranquillou 0, mais Average(), Max() et Min() balancent une exception. Avant d’appeler ces méthodes, assure-toi qu’il y a au moins un élément.

Erreur n°2 : passer une lambda avec la mauvaise signature.
Par exemple, si tu passes une string au lieu d’un nombre à une fonction d’agrégation (Sum, Max, etc.), tu vas avoir une erreur de compilation. C’est facile de se planter avec les méthodes anonymes.

Erreur n°3 : vérifier le nombre d’éléments de façon pas optimale.
La méthode Where(...).Count() crée d’abord une nouvelle collection, puis compte les éléments. Utilise plutôt Count(predicate) — il compte direct les éléments qui matchent et c’est plus rapide.

Erreur n°4 : oublier les particularités des types nullable en agrégation.
Si tu fais la somme sur des int?, Sum() ignore les null. C’est normal, mais ça peut surprendre si t’y penses pas.

2
Mission
C# SELF, niveau 32, leçon 1
Bloqué
Calcul de la somme des éléments d'un tableau
Calcul de la somme des éléments d'un tableau
Commentaires
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION