Einzelnen Beitrag anzeigen

globetrotter77

Registriert seit: 16. Jan 2009
Ort: Nürnberg
236 Beiträge
 
Delphi 10.3 Rio
 
#20

Re: TObjectList - Sort crash (D7)

  Alt 10. Feb 2009, 16:48
Sort ist eine Methode von TList, die als einzigen Parameter den Namen einer Function vom Typ TListSortCompare erwartet.
Diese Function MUSS exakt folgende Deklaration besitzen:
function funktionsname(Item1, Item2: Pointer): Integer; TList.Sort ruft nun wiederum, falls überhaupt etwas in der Liste vorhanden ist, die interne Methode QuickSort auf, die sich rekursiv auch wieder selber aufruft, allerdings mit immer kleiner werdenden Intervallen, daher auch endlich.
Die eigentliche Sortierung erfolgt dabei durch blitzschnelles Umschlichten der auf die einzelnen Elemente zeigenden Pointer.

Nachdem die Liste selbst nicht wissen kann, nach welchen Kriterien sortiert werden soll, muss hierzu eben diese genannte Function übergeben werden, die ebenfalls nur mit den Pointern aufgerufen wird.

Hier kann man nach Herzenslust Sortiervorgaben programmieren.
Entscheidend für den intern durchlaufenen Algorithmus ist einzig und alleine, ob ein Wert rauskommt, der <0, =0 oder >0 ist
Auch wenn -7 zurückgegeben wird, wird das nicht anders behandelt als -1.

Es bedeuten:
<0 Item2 ist "kleiner" als Item1, wird also "vorher" einsortiert
=0 Item2 ist "gleich" Item1, da ist die Reihenfolge egal
>0 Item2 ist "größer" als Item1, wird also "nachher" einsortiert

Wieso so rum und nicht so, wie man's aus der Funktion herauslesen würde, weiß kein Mensch.

Wenn du also eine Spezialsortierung für die Nullwerte brauchst, muss die Funktion daher lauten (ich schreibe die Vergleiche mal andersrum, damit das Ergebnis (zumindest für mich) besser lesbar wird):
Delphi-Quellcode:
function CompareNextStart(Item1, Item2: Pointer): Integer;
begin
  if (TMyItem(Item1).NextStart = 0) and (TMyItem(Item2).NextStart <> 0) then
    Result := -1 // Item2 < Item1
  else if (TMyItem(Item2).NextStart = 0) and (TMyItem(Item1).NextStart <> 0) then
    Result := +1 // Item2 > Item1
  else if (TMyItem(Item2).NextStart = 0) and (TMyItem(Item1).NextStart = 0) then
    Result := 0 // Item2 = Item1
  else // ab hier ist keiner der beiden Werte 0
  if TMyItem(Item2).NextStart < TMyItem(Item1).NextStart then
    Result := -1 // Item2 < Item1
  else if TMyItem(Item2).NextStart > TMyItem(Item1).NextStart then
    Result := +1 // Item2 > Item1
  else
    Result := 0; // Item2 = Item1
end;
Hab's nicht ausprobiert, aber so müsste es eigentlich stimmen!
  Mit Zitat antworten Zitat