10. november 2004 - 22:59Der er
14 kommentarer og 1 løsning
Sortere ArrayList efter indhold i en Class
Hej,
Jeg har en ArrayList som indeholder Class, og jeg ønsker at sortere det efter hvad min Class indeholder? altså en member value i min class, hvordan fikser jeg det?
public class MitObjekt { private int etNummer; public MitObjekt(int etNummer) { this.etNummer = etNummer; } public int GetObjektNummer() { return etNummer; } }
public class MitObjektComparer : IComparer { int IComparer.Compare(Object o1, Object o2) { return (((MitObjekt)o1).GetObjektNummer() - ((MitObjekt)o2).GetObjektNummer()); } }
class MainClass { public static void Main(string[] args) { ArrayList list = new ArrayList(); list.Add(new MitObjekt(3)); list.Add(new MitObjekt(2)); list.Add(new MitObjekt(1)); for(int i = 0; i < list.Count; i++) { Console.WriteLine(((MitObjekt)list[i]).GetObjektNummer()); } list.Sort(new MitObjektComparer()); for(int i = 0; i < list.Count; i++) { Console.WriteLine(((MitObjekt)list[i]).GetObjektNummer()); } } }
Ja, som Arne_v skriver kan du lave en klasse der implementerer IComparer, men du kan også lade de objekter på putter i din ArrayList (instanser af MitObjekt) arve fra IComparable.
Virker det på sammen måde hvis det er en string....? Kigger på det og vender tilbage hvis jeg ikke selv kan finde ud af det Hvis du smider et svar, skal du få dine point....
Synes Wisen skal have list point også for sin kommentar omkring at lade klassen arve fra IComparable....
Arne: har lavet dit om så det ser sådan her ud nu, og ser ud til at virke...: using System; using System.Collections;
public class MitObjekt : IComparer { private string etNummer; public MitObjekt(string etNummer) { this.etNummer = etNummer; }
public MitObjekt(){}
public string GetObjektNummer() { return etNummer; }
int IComparer.Compare(Object o1, Object o2) { return (((MitObjekt)o1).GetObjektNummer().CompareTo(((MitObjekt)o2).GetObjektNummer())); } }
class MainClass { public static void Main(string[] args) { ArrayList list = new ArrayList(); list.Add(new MitObjekt("Mikael")); list.Add(new MitObjekt("Syska")); list.Add(new MitObjekt("Anders")); list.Add(new MitObjekt("Niels")); list.Add(new MitObjekt("Stephan"));
Console.WriteLine("Før det bliver sorteret"); for(int i = 0; i < list.Count; i++) { Console.WriteLine(((MitObjekt)list[i]).GetObjektNummer()); }
list.Sort(new MitObjekt()); Console.WriteLine("Efter det blev sorteret"); for(int i = 0; i < list.Count; i++) { Console.WriteLine(((MitObjekt)list[i]).GetObjektNummer()); } } }
Det vil sige at når man kalder list.Sort(new MitObjekt()); så ved den godt at den skal bruge den IComparer.Compare fordi den bliver kaldt inde fra en Sort funktion???
Jeg tror iøvrigt at wisen mente IComparable og ikke IComparer.
Se dette udvidede eksempel:
using System; using System.Collections;
public class Foobar : IComparable { private int a; private string b; public Foobar() : this(0, "") { } public Foobar(int a, string b) { this.a = a; this.b = b; } public int A { get { return a; } set { a = value; } } public string B { get { return b; } set { b = value; } } public int CompareTo(object o) { return (a - ((Foobar)o).A); } public override string ToString() { return ("(" + a + "," + b + ")"); } }
public class FoobarAComparer : IComparer { int IComparer.Compare(Object o1, Object o2) { return (((Foobar)o1).A - ((Foobar)o2).A); } }
public class FoobarRevAComparer : IComparer { int IComparer.Compare(Object o1, Object o2) { return -(((Foobar)o1).A - ((Foobar)o2).A); } }
public class FoobarBComparer : IComparer { int IComparer.Compare(Object o1, Object o2) { return (((Foobar)o1).B.CompareTo(((Foobar)o2).B)); } }
public class FoobarRevBComparer : IComparer { int IComparer.Compare(Object o1, Object o2) { return -(((Foobar)o1).B.CompareTo(((Foobar)o2).B)); } }
class ManySort { private static void print(string descr, ArrayList list) { Console.Write(descr + ": ["); foreach(object o in list) { Console.Write(o); } Console.WriteLine("]"); } public static void Main(string[] args) { ArrayList list = new ArrayList(); list.Add(new Foobar(5, "AAAAA")); list.Add(new Foobar(4, "BBBB")); list.Add(new Foobar(3, "CCC")); list.Add(new Foobar(2, "DD")); list.Add(new Foobar(1, "E")); print("Original", list); list.Sort(); print("After natural sort (= sort on A)", list); list.Sort(new FoobarRevAComparer()); print("After reverse sort on A", list); list.Sort(new FoobarAComparer()); print("After sort on A", list); list.Sort(new FoobarBComparer()); print("After sort on B", list); list.Sort(new FoobarRevBComparer()); print("After reverse sort on B",list); } }
Pointen er at man vil lade klassen selv arve fra IComparable, hvis der er en enkelt naturlig søgning, eller lave nogle andre klasser som arver fra IComparer, hvis man skal bruge flere forskellige søgninger. Det er henholdsvis wisens og mit forslag.
Du havde valgt at lade klassen selv arve fra IComparer, hvilket er sådan lidt midt imellem.
Jeg ville bare understrege forskellen, da IComparer og IComparable ligner hinanden en hel del som ord, men rent faktisk er noget forskelligt.
ja, jeg er bare glad for at det virker lige nu, da det før var træls at det ikke stod alfabetisk, den størrer forskel finder jeg nok senere når jeg bliver bedre, vi er jo alle startet et sted :-P
// ouT
Synes godt om
Ny brugerNybegynder
Din løsning...
Tilladte BB-code-tags: [b]fed[/b] [i]kursiv[/i] [u]understreget[/u] Web- og emailadresser omdannes automatisk til links. Der sættes "nofollow" på alle links.