Archives Wild Code School
C#

POO C# - 2. Les extensions IEnumerable

Quête 45 sur 46

Après cette quête, tu auras un avant-goût de la puissance des extensions LINQ pour les types énumérables

Objectifs

  • Comprendre des notions de programmation fonctionnelle
  • Utiliser les extensions des IEnumerable

Toujours plus rapide

Les développeurs sont souvent sujet au temps. La qualité de leur projet, les bénéfices réalisés, les membres du projet qui viennent et qui partent ... Tout cela est lié au facteur temps ! Le temps est autant important par rapport aux performances d'un produit livrable que de son temps de développement.

Conséquemment à cette obsession du temps, les concepteurs de C# ont décidé d'implémenter dans leur langage des algorithmes supposés nous en faire gagner, beaucoup ...

Un paradigme différent des paradigmes procédural et orienté objet existe: il s'agit du paradigme fonctionnel. En programmation fonctionnelle, on considère que TOUT EST FONCTION, grossièrement. Ainsi, on ne manipule plus des objets mais des fonctions/méthodes retournant des résultats. La programmation fonctionnelle est idéale pour réaliser des opérations mathématiques sensibles et pointues. Il s'agit d'un paradigme à la pointe de la technologie et des techniques de développement avancées. Les langages associés au paradigme fonctionnel actuels sont donc très avancés et difficiles à maîtriser. Mais il est utile de les connaître et la façon de résoudre des problèmes dans ces langages est souvent plutôt classe.

Heureusement pour nous, les développeurs de C# connaissant les avantages des langages fonctionnels en ont apporté un bout dans C# pour que l'on puisse s'en servir pour gagner du temps. Et puis, la programmation fonctionnelle c'est cool en plus :).

↗
https://docs.microsoft.com/en-us/dotnet/api/system.linq.enumerable.where?view=netframework-4.8
docs.microsoft.com

Ils ont apporté quoi en particulier ?

Une foultitude de choses mais nous allons nous concentrer sur les extensions IEnumerable. Comme il s'agit d'extensions, elles ne sont pas nativement présentes dans les IEnumerable. Afin de pouvoir accéder aux méthodes LINQ sur les énumérables il faut que tu importes le bon namespace: System.Linq.

L'itération V2

Tu sais itérer sur un énumérable. Du moins, si tu es arrivé jusque là c'est que tu sais le faire. Ainsi, lorsque tu veux réaliser la somme d'un tableau d'entiers:

cs
int sum = 0;
foreach (int value in integers)
{
    sum = sum + value;
}

Et dès lors que tu itères sur une séquence, cet éternel pattern est écrit puis réecrit alors que tu implémentes les specs de ton projet. Ca peut être un peu lassant au final, et parfois compliqué de traiter toutes les séquences avec des itérations.

Pour t'éviter l'ennui et rafraîchir ton cerveau avec de nouvelles connaissances, et surtout pour améliorer la qualité et la rapidité d'écriture de ton code, les concepteurs de C# ont mis à disposition des méthodes qui facilitent tes itérations, tu pourras quasiment toute les écrire en une seule ligne !

Ainsi, l'itération précédente renvoyant une somme peut être écrite:

cs
int sum = integers.Aggregate((x, y) => x + y);

Pardon ?

Oui, je sais, c'est plutôt bizarre, mais tout ce que tu fais au sein du foreach et réalisé dans cette simple ligne.

Je vais décortiquer un peu:

  1. On crée un entier appelé sum

  2. On affecte à sum le retour de la méthode Aggregate de l'objet integers, qui est un type énumérable (dépend de l'interface IEnumerable)

  3. On passe quelque chose de bizarre en argument de la méthode Aggregate.

Ce quelque chose de bizarre est une méthode delegate sous la forme d'un lambda. C'est-à-dire que c'est une méthode exprimée en très peu de lignes et dépourvue de signature. Cette méthode renvoie la somme de deux éléments de integers.

Entre parenthèses sont les deux éléments de integers que la lambda prend en paramètres. x est un élément de l'énumérable, et y un deuxième. Cette lambda est exécutée jusqu'à ce que integers ait été entièrement parcouru. Ainsi, lors du dernier appel de la lambda en argument de Aggregate, x est égal à la somme de tous les éléments de integersavant le dernier, et y le dernier élément.

Ca à l'air sympa ! Il y en a d'autres comme ça non ?

↗
MSDN - Enumerable
docs.microsoft.com
↗
Les Lambda Expression en C#
geeksforgeeks.org

Where

Il existe une foultitude de méthodes apportées par l'extension LINQ. Je vais présenter les plus utiles.

La méthode Where permet de retourner un sous-ensemble de tous les éléments d'un ensemble satisfaisant un prédicat. Le mot prédicat est synonyme d'expression booléenne. Il s'agit donc d'un ensemble de critères satisfaits ou non.

cs
using System.Linq;
namespace WHERE
{
    public class Program
    {
        public void Main(string[] args)
        {
            List<int> integers = new List<int> {1, 2, 3, 4, 5, 6, 7, 8, 9};
            List<int> integersLowerThanFive = integers.Where((x) => x < 5);
            foreach (int value in integersLowerThanFive)
            {
                Console.Write(value + " ");
            }
        }
    }
}

Le code ci-dessus affiche tous les éléments de integers étant inférieur à 5. A l'écran sera donc affiché:1 2 3 4. La méthode Where a renvoyé tous les éléments de integers satisfaisant le prédicat renseigné par la delegate sous forme de lambda. Précidat étant qu'un entier est inférieur à 5.

 Ressources

Challenge

Challenge

Prédicats en folie

Produit un programme qui fait la moyenne des éléments d'un tableau d'entiers pour tout élément inférieur ou égal à un entier n.

Critères de validation

  • La moyenne doit être réalisée par une ou plusieurs méthodes des extensions IEnumerable de System.Linq
  • L'utilsateur doit spécifier n lors de l'exécution du programme
  • Le tableau et la moyenne sont affichés à l'écran