Avatar billede Syska Mester
10. november 2004 - 22:59 Der 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?

// oUT
Avatar billede arne_v Ekspert
10. november 2004 - 23:01 #1
Jeg lavede engang dette eksempel:

using System;
using System.Collections;

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());
        }
    }
}
Avatar billede wisen Nybegynder
11. november 2004 - 09:03 #2
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.
Avatar billede Syska Mester
11. november 2004 - 09:53 #3
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....
Avatar billede wisen Nybegynder
11. november 2004 - 09:56 #4
Ja, System.String implementerer IComparable
Avatar billede arne_v Ekspert
11. november 2004 - 09:56 #5
Hvis det er strenge du skal sammenligne skal du bruge Compare eller CompareTo
fordi du kan ikke bruge minus. Men ellers er det helt det samme.
Avatar billede arne_v Ekspert
11. november 2004 - 09:56 #6
svar
Avatar billede Syska Mester
11. november 2004 - 16:16 #7
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???
Avatar billede arne_v Ekspert
11. november 2004 - 16:31 #8
Ja.

For klasser som har en "naturlig orden" laver man bare en Compare i klassen.

Hvis man vil supportere flere forskellige sorteringer på en klasse, så
bruger man en Comparer klasse.

Det har ikke noget med int versus string at gøre. Min kommentar 09:56:29
var på indmaden i en Comparer klasse.
Avatar billede Syska Mester
11. november 2004 - 18:05 #9
Det med int vs string kunne jeg godt regne ud, jeg har jo fået det til at virke *jubiiii*
Avatar billede arne_v Ekspert
12. november 2004 - 00:00 #10
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);
    }
}
Avatar billede arne_v Ekspert
12. november 2004 - 00:02 #11
wisen skrev IComparable - men dit eksempel valgte du at lade objektet arve
fra IComparer - der er en stor forskel
Avatar billede Syska Mester
12. november 2004 - 12:43 #12
Altså det du siger er at IComparable ikke kan bruges i mit tilfælde ( kan dog godt se at jeg har brugt IComparer ) da mit skal sorteres alfabetisk....

Men så skal du jo alligevel have alle point :-P
Avatar billede arne_v Ekspert
12. november 2004 - 12:50 #13
Jo IComparable kan godt bruges i dit eksempel. wisens betragtning er helt korrekt.
Avatar billede arne_v Ekspert
12. november 2004 - 12:53 #14
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.
Avatar billede Syska Mester
12. november 2004 - 13:03 #15
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
Avatar billede Ny bruger Nybegynder

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.

Loading billede Opret Preview
Kategori
IT-kurser om Microsoft 365, sikkerhed, personlig vækst, udvikling, digital markedsføring, grafisk design, SAP og forretningsanalyse.

Log ind eller opret profil

Hov!

For at kunne deltage på Computerworld Eksperten skal du være logget ind.

Det er heldigvis nemt at oprette en bruger: Det tager to minutter og du kan vælge at bruge enten e-mail, Facebook eller Google som login.

Du kan også logge ind via nedenstående tjenester