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.