Archives par mot-clé : CompareTo

The lambda expression in C # moving up another gear

The lambda expression in C # moving up another gear
by Ettougourti Mohamed Ali

 

You would be surprised to learn that we have done in our previous section touched easy aspects of using the lambda expression with vectors and arrays.
The « normal » use relates the well-known conventional vectors.
But what if we plan to use vectors of a particular type?

A vector class or structure defined by us?
Two examples: the first milking fractions vector,

the second relates to a vector of musical notes.

In both cases structure are defined by us.
Let’s start with the first example by creating together a special class which is called « fraction »

Class fraction {};

To be visible from all public we qualify the class as public.
Public class fraction {};
Two constructors are provided to initialize the class:
Public fraction (int d);
And
Public fraction (int n, int d);
The first constructor assumes the numerator of the fraction equal to 1.

The instruction
New fraction (2);
Gives a fraction of a half 1/2 ..

The second most explicit constructor requires and the numerator and the denominator.
The instruction
New fraction (2, 4);
Gives a fraction of 2/4 two quarters or a half.
Here is all the concocted code.

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;
}
}

We propose to create a vector of class fractions that we simply appoint x.

Fraction x = new fraction [5];

Initializing the array with a series of 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);

The challenge we face is to use the lambda expression to process data of the vector x to find the maximum, the minimum and their respective positions for example.

The flood instruction

fraction max= x.Max ();

Will cause a compiler error because the fraction class contains no CompareTo () method that would allow comparison between the different elements of the vector. CompareTo method is necessary to find the maximum and the minimum values.
The compiler standing by its CompareTo method we must comply.
We resume therfore our code written for the « fraction » class by declaring the fraction base class IComparable.

public class fraction: IComparable
And then just adding a CompareTo method.

int CompareTo (object obj)

{

fraction f = (fraction) obj;

int n = f.num * den;

int d = f.den * den;

int num = n2 * f.den;

int d2 = den * f.den;

if (n == n2) return 0;

else if (n2> n) return 1;

return -1;

}

The CompareTo method begins by calculating the common denominator between the two fractions.

If both are equal numerators our method returns zero to say that both fractions are equal if n2 is greater than n the method returns 1 otherwise it returns -1;

Our fraction rewritten class now looks like the following code:

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 num = n2 * f.den;

int d2 = den * f.den;

if (n == n2) return 0;

else if (n2> n) return 1;

return -1;

}

}

we can now safetly seek the greatest value of the vector x.

fraction max = x.MAX();

Or

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

Max takes the value of 1/4;

The instruction

Fraction min = x.Min();

Or

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

refers 1/24;

To sort the vector from the smallest fractions to the largest we can still use the lambda expression with instruction orderby

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

the vector x is now ordered as follows

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

The instruction

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

Operates a descending sort.

The reverse statement is also operational.

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

The instruction indexof already encountered works just as well.

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

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

(20)

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

 

 

 

 

 

 

 

(54)