l’expression lambda dans le c# : passer à la vitesse supérieure

l’expression lambda en c#: passer à la vitesse supérieure :

vous seriez bien étonnés d’apprendre que nous n’avons fait dans nos précédents article qu’effleurer les différents aspects de l’utilisation de l’expression lambda avec les vecteurs et les tableaux

l’utilisation « normale »  concerne les différents tableaux et vecteurs de type conventionnel bien connu.

Que faire si nous projetons d’utiliser des vecteurs d’un type bien particulier. Un vecteur de classe ou de structure définies par nos soins ?

Deux exemples : le premier  traite d’vecteur de fractions , le deuxième se rapporte à un vecteur de notes musicales dont la structure a été définie par nos soins.

Commençons par le premier exemple en créant ensemble une classe spéciale qui porte le nom de « fraction »

Class fraction  { } ;

Pour que la classe soit visible de partout nous la qualifions de publique.

Public class fraction {} ;

Deux constructeurs sont prévus pour initialiser la classe :

Public fraction (int d) ;

Et

Public fraction (int n, int d) ;

Le premier constructeur présume le numérateur de la fraction égal à 1. L’instruction

New fraction (2) ;

Nous donne donc une fraction d’un demi 1/2..

Le deuxième constructeur plus explicite exige d’indiquer et le numérateur et dénominateur. L’instruction

New fraction (2,4) ;

Nous donne une fraction de deux quarts 2/4 soit toujours la moitié.

Voici tout le code concocté.

public class fraction  

        {

    public int num;

            public int den;

 

          public  fraction (int d)

            {

                this.num = 1;

                this.den = d;

            }

           public fraction (int n, int d)

            {

                this.num = n;

                this.den = d;

            }

         }

Nous proposons ensuite de créer un tableau ou un vecteur de fractions qu’on nommera simplement x.

Fraction x= new fraction [5] ;

Initialisons le tableau avec une suite de fractions

            x[0] = new fraction(1, 10);

            x[1] = new fraction(1, 4);

            x[2] = new fraction(1, 24);

            x[3] = new fraction(1, 10);

            x[4] = new fraction(1, 5);

le défi que nous devons relever est celui d’utiliser l’expression lambda pour traiter des données du vecteur x. trouver par exemple la maximale, la minimale, leurs positions respectives ?

L’instruction crue

fraction max = x.Max();

Entraîne une erreur du compilateur attirant notre attention sur le fait que la classe fraction ne contient aucune méthode CompareTo() qui autoriserait la comparaison entre les différents éléments du vecteur. Méthode nécessaire et suffisante pour trouver la valeur maximale et éventuellement la valeur minimale.

Inutile d’insister. le compilateur tenant bon à sa méthode CompareTo force pour nous d’obtempérer.

Nous reprenons donc notre code écrit pour   la classe « fraction » en déclarant la classe base IComparable.

public class fraction  : IComparable

et en y ajoutant la fameuse méthode CompareTo.

int CompareTo (object obj)

            {

                fraction f = (fraction)obj;

                int n = f.num * den;

                int d = f.den * den;

                int n2 = num * f.den;

                int d2 = den * f.den;

                if(n == n2 )return 0;

                else if (n2 > n) return 1;

                return -1;

    }

La méthode CompareTo commence par calculer le dénominateur commun entre les deux fractions.

Si les deux numérateurs sont égaux notre méthode retourne   zéro pour dire que les deux fractions sont égales si n2 est supérieure à n la méthode retourne 1 sinon elle retourne -1 ;

Notre classe fraction réécrite ressemble maintenant au code suivant :

public class fraction  : IComparable

        {

             public int num;

            public int den;

 

          public  fraction (int d)

            {

                this.num = 1;

                this.den = d;

            }

 

           public fraction (int n, int d)

            {

                this.num = n;

                this.den = d;

            }

       public  int CompareTo (object obj)

            {

                fraction f = (fraction)obj;

                int n = f.num * den;

                int d = f.den * den;

                int n2 = num * f.den;

                int d2 = den * f.den;

                if(n == n2 )return 0;

                else if (n2 > n) return 1;

                 return -1;

  }

}

Désormais nous pouvons sans craindre les foudres du compilateur chercher la plus grande valeur du vecteur x.

Fraction max= x.Max() ;

Ou

fraction max = x.Max(b=> b);

max prend la valeur de 1/4 ;

L’instruction

Fraction min= x.Min() ;

Ou encore

fraction min = x.Min(b=> b);

Nous renvoie 1/24 ;

Pour trier le vecteur de fractions de la plus petite à la plus grande, tri dit ascendant, nous pouvons toujours utiliser l’expression lambda avec l’instruction linq orderby

x = x.OrderBy(b=> b).ToArray ();

le vecteur x est désormais ordonné comme suit

1/24, 1/10 , 1/10 , 1/5, 1/4

L’instruction

x = x.OrderByDescending(b => b).ToArray();

Opère un tri dit descendant.

L’instruction reverse est tout aussi opérationnelle.

x = x.Reverse().ToArray();

  L’instruction indexof déjà rencontrée marche tout aussi bien.

 int pos = x.ToList().IndexOf(max);

 pos = x.ToList().IndexOf(min);

 

 

 

 

 

 

 

(40)