Entwickler-Ecke
Grafische Benutzeroberflächen (VCL & FireMonkey) - TObjectList Sortiern
martin300 - Do 21.05.09 13:15
Titel: TObjectList Sortiern
hallo,
in einer Klasse(TMList) befindet sich eine TObjectList die viele Objekte der Klasse (TItem) speichert.
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.
Delphi-Quelltext
1:
| MyList.objlst.Sort(@TMlist.VergleicheItem); |
Mit der Vergleichsfunktion
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
Narses: Topic aus Sonstiges (Delphi) verschoben am Do 21.05.2009 um 22:47
ffgorcky - 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 [
http://www.delphi-forum.de/viewtopic.php?t=59408&highlight=string+sort].
Und bei Integer-Variablen musst Du doch nur
Delphi-Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9:
| if TItem(ITem1).ziffer>TItem(ITem2).ziffer then begin zwischenAblage:=TItem(ITem1).ziffer; TItem(ITem1).ziffer:=TItem(ITem2).ziffer; TItem(ITem2).ziffer:=zwischenAblage; end; |
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:
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 zwischenAblage:=TItem(ITem1).ziffer; TItem(ITem1).ziffer:=TItem(ITem2).ziffer; TItem(ITem2).ziffer:=zwischenAblage; WarNochEinTauschNoetig:=true; end; end; |
martin300 - 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.
Gausi - 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.
martin300 - Do 21.05.09 15:17
Das Ergebnis der Compare Funktion ist -1 , 0 oder +1.
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 - 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 :
Delphi-Quelltext
1: 2: 3:
| function VergleicheWerte (Item1, Item2: Pointer): integer; ... DatenObjektListe.Sort (@VergleicheWerte); |
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.
Martok - Do 21.05.09 18:00
Callback-Funktionen sind eigentlich nie Methoden. Das steht auch überall in der Delphi-Hilfe:
TListSortCompare (Typ)
1:
| type TListSortCompare = function (Item1, Item2: Pointer): Integer; |
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; |
martin300 - Fr 22.05.09 13:21
Danke.
Entwickler-Ecke.de based on phpBB
Copyright 2002 - 2011 by Tino Teuber, Copyright 2011 - 2025 by Christian Stelzmann Alle Rechte vorbehalten.
Alle Beiträge stammen von dritten Personen und dürfen geltendes Recht nicht verletzen.
Entwickler-Ecke und die zugehörigen Webseiten distanzieren sich ausdrücklich von Fremdinhalten jeglicher Art!