Noen gang lurt på hvordan man ordner støtte for å sortere objekter på flere forskjellige måter. F.eks. slik mange nettbutikker gjør, hvor de tilbyr deg sortering på pris, mest aktuelt, popularitet, o.s.v.?
Dette er enkelt å ordne f.eks. med grensesnittet IComparer. Men først trenger man en eksempelklasse som senere skal gi de objektene man ønsker å sortere:
public class Vare
{
public string Navn { get { return navn; } }
private string navn;
public string Produsent { get { return produsent; } }
private string produsent;
public int Pris { get { return pris; } }
private int pris;
public DateTime Lanseringsdato { get { return lanseringsdato; } }
private DateTime lanseringsdato;
public Vare(string navn, string produsent, int pris, DateTime lanseringsdato)
{
this.navn = navn;
this.produsent = produsent;
this.pris = pris;
this.lanseringsdato = lanseringsdato;
}
public override string ToString()
{
string info = "";
info += "----------------------------------------------------------------------\n";
info += "Navn: " + navn + "\n";
info += "Produsent: " + produsent + "\n";
if (lanseringsdato != DateTime.MinValue)
{
info += "Lansert en gang etter: " + lanseringsdato.Day + "." + lanseringsdato.Month + "." + lanseringsdato.Year + "\n";
}
info += "Selges for " + pris + " NOK\n";
info += "----------------------------------------------------------------------";
return info;
}
public static IComparer SorterBrukPriser { get { return new VareSortering.Prisen(); } }
public static IComparer SorterBrukProdusent { get { return new VareSortering.Produsent(); } }
public static IComparer SorterBrukLanseringsdato { get { return new VareSortering.Lanseringsdato(); } }
}
Her er det egentlig ikke så mye som er interessant, bortsett fra de tre siste linjene som man refererer til når man vil bruke de forskjellige sorteringsmåtene.
Disse implementeres i det som blir en hjelpeklasse til klassen Vare over:
public class VareSortering
{
public class Prisen : IComparer
{
public int Compare(object objekt1, object objekt2)
{
Vare vare1 = objekt1 as Vare;
Vare vare2 = objekt2 as Vare;
if (vare1 != null && vare2 != null)
{
if (vare1.Pris < vare2.Pris)
{
return -1;
}
else if (vare1.Pris > vare2.Pris)
{
return 1;
}
else
{
return 0;
}
}
else
{
throw new ArgumentException("Begge objekt som skal sammenlignes må være varer!");
}
}
}
public class Produsent : IComparer
{
public int Compare(object objekt1, object objekt2)
{
Vare vare1 = objekt1 as Vare;
Vare vare2 = objekt2 as Vare;
if (vare1 != null && vare2 != null)
{
if (vare1.Produsent.CompareTo(vare2.Produsent) < 0)
{
return -1;
}
else if (vare1.Produsent.CompareTo(vare2.Produsent) > 0)
{
return 1;
}
else
{
return 0;
}
}
else
{
throw new ArgumentException("Begge objekt som skal sammenlignes må være varer!");
}
}
}
public class Lanseringsdato : IComparer
{
public int Compare(object objekt1, object objekt2)
{
Vare vare1 = objekt1 as Vare;
Vare vare2 = objekt2 as Vare;
if (vare1 != null && vare2 != null)
{
if (vare1.Lanseringsdato.Year < vare2.Lanseringsdato.Year)
{
return -1;
}
else if (vare1.Lanseringsdato.Year > vare2.Lanseringsdato.Year)
{
return 1;
}
else
{
if (vare1.Lanseringsdato.Month < vare2.Lanseringsdato.Month)
{
return -1;
}
else if (vare1.Lanseringsdato.Month > vare2.Lanseringsdato.Month)
{
return 1;
}
else
{
if (vare1.Lanseringsdato.Day < vare2.Lanseringsdato.Day)
{
return -1;
}
else if (vare1.Lanseringsdato.Day > vare2.Lanseringsdato.Day)
{
return 1;
}
else
{
return 0;
}
}
}
}
else
{
throw new ArgumentException("Begge objekt som skal sammenlignes må være varer!");
}
}
}
}
Her er VareSortering gjort til en egen klasse utenfor Vare, men den kunne også vært opprettet inni og gjort privat da omverdenen ikke trenger direkte tilgang.
Og endelig for å teste om dette henger sammen og fungerer kan man kjøre følgende:
class Program
{
static void Main(string[] args)
{
Vare[] varer = new Vare[5];
varer[0] = new Vare("Intel Pentium G4400 3.3GHz Socket 1151 Box", "Intel", 533, new DateTime(2015, 8, 1));
varer[1] = new Vare("Corsair Vengeance LPX Black DDR4 PC19200/2400MHz CL14", "Corsair", 399, new DateTime(2015, 1, 1));
varer[2] = new Vare("ASUS Prime B250M-C", "ASUS", 858, new DateTime(2015, 1, 1));
varer[3] = new Vare("Fractal Design Core 1100 (Sort)", "Fractal Design", 379, DateTime.MinValue);
varer[4] = new Vare("Corsair VS450 V2 450W", "Corsair", 419, new DateTime(2015, 1, 1));
// Før sortering
Console.WriteLine("Før sortering:");
foreach (Vare vare in varer) Console.WriteLine(vare);
Console.WriteLine();
// Etter prissortering
Console.WriteLine("Etter prissortering:");
Array.Sort(varer, Vare.SorterBrukPriser);
foreach (Vare vare in varer) Console.WriteLine(vare);
Console.WriteLine();
// Etter produsentsortering
Console.WriteLine("Etter produsentsortering:");
Array.Sort(varer, Vare.SorterBrukProdusent);
foreach (Vare vare in varer) Console.WriteLine(vare);
Console.WriteLine();
// Etter lanseringsdato
Console.WriteLine("Etter lanseringsdatosortering:");
Array.Sort(varer, Vare.SorterBrukLanseringsdato);
foreach (Vare vare in varer) Console.WriteLine(vare);
Console.WriteLine();
Console.ReadLine();
}
}
.. som da resulterer i:
Altså virker alle de tre forskjellige sorteringsmåtene, og har man flere man ønsker å legge inn er dette ikke noe problem.
