Autor Beitrag
martin300
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 186
Erhaltene Danke: 2



BeitragVerfasst: Do 21.05.09 13:15 
hallo,
in einer Klasse(TMList) befindet sich eine TObjectList die viele Objekte der Klasse (TItem) speichert.

ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
  TMList = class(Tobject)
    objlst : TObjectList;
    function VergleicheItem(Item1, Item2: Pointer): Integer;
  end;

  TItem = class (TObject)
    ziffer : Integer;
    constructor create (value : Integer);
  end;


Nun sollen die Einträge der TObjectListe aufsteigend sortiert werden. Kriterium Ziffer in TItem. Die TObjectList bietet die Funktion Sort an.

ausblenden Delphi-Quelltext
1:
 MyList.objlst.Sort(@TMlist.VergleicheItem);					


Mit der Vergleichsfunktion
ausblenden Delphi-Quelltext
1:
2:
3:
4:
function TMList.VergleicheItem(Item1, Item2: Pointer): Integer;
begin
    Result := CompareValue(TItem(ITem1).ziffer, TItem(Item2).ziffer);
end;

soll die Liste sortiert werden.
Sobald versucht wird die Liste zu sortieren kommt eine Zugriffsverletzung.

Was möchte ich : Die vielen TItem die sich in einer TObjectListe befinden sollen aufsteigend in der Liste vorhanden sein.


Moderiert von user profile iconNarses: Topic aus Sonstiges (Delphi) verschoben am Do 21.05.2009 um 22:47
ffgorcky
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 573

WIN XP/2000 & 7Prof (Familie:Win95,Win98)

BeitragVerfasst: Do 21.05.09 13:32 
Was genau sind das denn für Objekte?
Bei Strings gibt es ja recht einfache Lösungen, wie zum Beispiel diese hier.
Und bei Integer-Variablen musst Du doch nur
ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
if TItem(ITem1).ziffer>TItem(ITem2).ziffer then
            begin
           //Wenn also die Ziffer in Item1 größer, aber aufsteigende Sortierung vorgesehen ist, 
           //  dann mache einen Dreieckstausch:
            zwischenAblage:=TItem(ITem1).ziffer;
            TItem(ITem1).ziffer:=TItem(ITem2).ziffer;
            TItem(ITem2).ziffer:=zwischenAblage;
            end;
        //sonst braucht er ja nichts zu machen.

Das musst Du dann nur ziemlich oft (maximal so oft, wie das Array lang ist) durchlaufen lassen.
Oder nach was für einem Wert möchtest Du sie vergleichen?

PS: Ich würde Dir dabei empfehlen, dass Du dann eine boolsche Variable WarNochEinTauschNoetig mit einbaust und diese zu Anfang (also vor der Schleife) und in der Schleife nur dann auf True setzt, wenn Du einen Dreieckstausch machen musstest. Also würde die ganze Abhandlung dann so aussehen:
ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
WarNochEinTauschNoetig:=True
While WarNochEinTauschNoetig do
  begin
  WarNochEinTauschNoetig:=false;
  for i:=0 to Length(ZuSortierendeListe)-2 do
    if TItem(ZuSortierendeListe[i]).ziffer>TItem(ZuSortierendeListe[i+1]).ziffer then
            begin
           //Wenn also die Ziffer in Item1 größer, aber aufsteigende Sortierung vorgesehen ist, 
           //  dann mache einen Dreieckstausch:
            zwischenAblage:=TItem(ITem1).ziffer;
            TItem(ITem1).ziffer:=TItem(ITem2).ziffer;
            TItem(ITem2).ziffer:=zwischenAblage;
           //Hier dann einen erneuten Durchlazf für nötig erklären:
            WarNochEinTauschNoetig:=true;
            end;
  end;


Zuletzt bearbeitet von ffgorcky am Do 21.05.09 14:07, insgesamt 6-mal bearbeitet
martin300 Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 186
Erhaltene Danke: 2



BeitragVerfasst: Do 21.05.09 13:44 
Es sind mehrere Objekte vom Typ TItem die sich in der Liste befinden. Was ich möchte ist eigentlich etwas ganz "einfaches". Die Objekte die sich in einer TObjectList befinden in der Liste sortieren. Nur komme ich mit der Sort Funktion von TObjectList nicht zurecht. Anhand der Integer Variable Ziffer möchte ich die Objekte in der Liste aufsteigend sortieren.


Zuletzt bearbeitet von martin300 am Do 21.05.09 14:13, insgesamt 1-mal bearbeitet
Gausi
ontopic starontopic starontopic starontopic starontopic starontopic starofftopic starofftopic star
Beiträge: 8548
Erhaltene Danke: 477

Windows 7, Windows 10
D7 PE, Delphi XE3 Prof, Delphi 10.3 CE
BeitragVerfasst: Do 21.05.09 13:56 
Darf die Compare-Funktion denn eine Methode sein? Ich meine, dass das eine lose Funktion sein muss - probier das mal aus.

_________________
We are, we were and will not be.
martin300 Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 186
Erhaltene Danke: 2



BeitragVerfasst: Do 21.05.09 15:17 
Das Ergebnis der Compare Funktion ist -1 , 0 oder +1.
ausblenden Delphi-Quelltext
1:
2:
3:
4:
 if(TItem(Item1).ziffer = 0)then Result:=1
  else if(TItem(Item1).ziffer > TItem(Item2).ziffer)then Result:=1
  else if(TItem(Item1).ziffer < TItem(Item2).ziffer)then Result:=-1
  else Result:=0;

Die ist fast richtig. Der Aufruf der Vergleichsfunktion passt aber noch nicht.
hansa
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 3079
Erhaltene Danke: 9



BeitragVerfasst: Do 21.05.09 17:36 
Wie wärs denn mal damit, nicht dauernd zu wiederholen, dass es nicht geht, sondern die gemachten Vorschläge zu testen ? :shock: Insbesondere den von Gausi. Mit "loser Funktion" meint er eine einzelne Funktion. Habe bei mir nachgeguckt :

ausblenden Delphi-Quelltext
1:
2:
3:
function VergleicheWerte (Item1, Item2: Pointer): integer;
...
DatenObjektListe.Sort (@VergleicheWerte); // Aufruf so


Und das funktioniert. Kann keine nähere Begründung dafür geben, warum es so sein muss, aber ich kann dir versichern, dass einiges dafür spricht, dass es so ist. Normalerweise hätte ich das nämlich nicht so gemacht.

_________________
Gruß
Hansa
Martok
ontopic starontopic starontopic starontopic starontopic starontopic starofftopic starofftopic star
Beiträge: 3661
Erhaltene Danke: 604

Win 8.1, Win 10 x64
Pascal: Lazarus Snapshot, Delphi 7,2007; PHP, JS: WebStorm
BeitragVerfasst: Do 21.05.09 18:00 
Callback-Funktionen sind eigentlich nie Methoden. Das steht auch überall in der Delphi-Hilfe:
ausblenden TListSortCompare (Typ)
1:
type TListSortCompare = function (Item1, Item2: Pointer): Integer;					


ausblenden Sort (Beispiel)
1:
2:
3:
4:
5:
6:
7:
8:
function CompareNames(Item1, Item2: Pointer): Integer;
begin
  Result := CompareText((Item1 as TComponent).Name, (Item2 as TComponent).Name);
end;
procedure TForm1.Button1Click(Sender: TObject);
begin
  List1.Sort(@CompareText);
end;

_________________
"The phoenix's price isn't inevitable. It's not part of some deep balance built into the universe. It's just the parts of the game where you haven't figured out yet how to cheat."
martin300 Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 186
Erhaltene Danke: 2



BeitragVerfasst: Fr 22.05.09 13:21 
Danke.