Questo è uno di quei problemi che nascono quando si comincia a lavorare con moli di dati decisamente elevati e per i quali occorre magari un modo per ordinarli senza dover operare con algoritmi di sort vari tra tutti quelli disponibili e tanto cari agli amici matematici che si occupano di informatica. Il framework infatti, ci mette a disposizione un metodo automatizzato per ordinare automaticamente un qualsiasi tipo di collezione di dati non FIFO (quindi ArrayList, List ecc.).
Questo metodo consiste nell’utilizzare il metodo Sort che appartiene appunto a queste serie di dati:
ArrayList lista = new ArrayList();
lista.Add("C");
lista.Add("B");
lista.Add("A");
lista.Sort();
Quello che otteniamo è così una lista ordinata in ordine alfabetico, quindi avremo prima l’elemento “A”, poi “B” ed infine “C”.
NB: E’ possibile ordinare in senso inverso tramite l’utilizzo di 2 metodi separatamente. Per primo il metodo Sort che ordina in un verso e poi tramite il metodo Reverse che ordina la collezione di dati in senso inverso all’attuale. [1]
Quello che però più spesso accade è voler decidere noi il metodo di ordinamento. Supponiamo ad esempio di avere la necessità di ordinare le lettere A, B e C secondo questo ordine:
- B > C
- C > A
che implicitamente significa che B > C. Quindi vogliamo avere come ordine finale “B”, “C” e “A”. Ovviamente tramite i metodi standard questo non è possibile, ecco perciò che vediamo come fare grazie all’interfaccia IComparer.
Il metodo Sort infatti, prevede un argomento di tipo IComparer, ovvero un oggetto che mette a disposizione un metodo Compare che prevede come argomenti due valori di tipo object e che ragiona secondo la seguente logica:
- Se x < y allora ritorno -1
- Se x > y allora ritorno 1
- Se x = y allora ritorno 0
Creo così una classe MyStringComparer che estende l’interfaccia e quindi il suddetto metodo ed al cui interno occorre mettere il codice per fare in modo di ordinare i valori nel modo che vogliamo noi secondo la logica appena descritta:
public class MyStringComparer : IComparer
{
#region IComparer Members
public int Compare(object objx, object objy)
{
//se sono uguali non ho problemi e ritorno 0
if (objx.Equals(objy))
return 0;
switch (objx.ToString())
{
//se il primo valore è B, allora è sempre minore degli altri
case "B":
return -1;
//se è C devo controllare
case "C":
//perchè se è A allora va prima altrimenti dopo
if (objy.ToString() == "A")
return -1;
else
return 1;
//se è A invece va sempre dopo gli altri
case "A":
return 1;
}
return 0;
}
#endregion
}
A questo punto, proviamo questo codice:
static void Main(string[] args)
{
ArrayList lista = new ArrayList();
lista.Add("C");
lista.Add("B");
lista.Add("A");
lista.Add("C");
lista.Add("B");
lista.Add("A");
lista.Sort(new MyStringComparer());
foreach (string str in lista)
{
Console.WriteLine(str);
}
Console.Read();
}
Ovviamente, ciò che otteniamo è la serie: BBCCAA, esattamente come volevamo ![]()
Ora che siamo giunti a questa conclusione, ci viene però in mente che potremmo trovare un modo per migliorare l’ordinamento inverso della lista, visto che prima usavamo 2 metodi per farlo… invece è possibile grazie ad 1 solo. Creiamo un comparatore inverso! [2]
public class ReverseOrder : IComparer
{
#region IComparer Members
public int Compare(object objx, object objy)
{
return String.Compare((string)objx, (string)objy) * -1;
}
#endregion
}
Ecco fatto. Relativamente semplice, ma soprattutto molto ordinato (scusate il gioco di parole
)
Alla prossima! ![]()
Mi chiamo Denis Billi, ho 25 anni e sono della provincia di Ravenna. Mi sono laureato nell'estate del 2008 presso la facoltà di Ingegneria Informatica dell'università di Bologna e attualmente sto seguendo i corsi per la Laurea Specialistica in Ingegneria Informatica sempre all'università di Bologna.