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);
(48)