Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Object-Pascal / Delphi-Language (https://www.delphipraxis.net/32-object-pascal-delphi-language/)
-   -   Delphi TList.Sort Rückwärts? (https://www.delphipraxis.net/138238-tlist-sort-rueckwaerts.html)

xZise 5. Aug 2009 16:59


TList.Sort Rückwärts?
 
Hallo ihr,
kann man bei der TList auch rückwärts sortieren? Oder muss jedesmal eine neue Compare-Methode erstellen? Einmal für Vorwärts und einmal für Rückwärts?

MfG
xZise

DeddyH 5. Aug 2009 17:01

Re: TList.Sort Rückwärts?
 
Zitat:

Zitat von xZise
Oder muss jedesmal eine neue Compare-Methode erstellen? Einmal für Vorwärts und einmal für Rückwärts

Eine andere Möglichkeit ist mir persönlich nicht bekannt und sooo viel Aufwand ist das ja nicht.

SirThornberry 5. Aug 2009 17:08

Re: TList.Sort Rückwärts?
 
Je nach dem wie du die Liste dann verwendest ist es vielleicht weniger Aufwand die Einträge einfach umgekehrt auszulesen.

Die Muhkuh 5. Aug 2009 17:18

Re: TList.Sort Rückwärts?
 
Du kannst ja genau so gut vorwärts sortieren und rückwärts auslesen.

Sollte eigentlich kein Unterschied machen zu rückwärts sortieren und vorwärts auslesen.

xZise 5. Aug 2009 17:48

Re: TList.Sort Rückwärts?
 
Zitat:

Zitat von SirThornberry
Je nach dem wie du die Liste dann verwendest ist es vielleicht weniger Aufwand die Einträge einfach umgekehrt auszulesen.

Zitat:

Zitat von Die Muhkuh
Du kannst ja genau so gut vorwärts sortieren und rückwärts auslesen.

Sollte eigentlich kein Unterschied machen zu rückwärts sortieren und vorwärts auslesen.

Jain. Für das Ergebnis nicht, aber dann müsste ich speichern, wie rum ich sortiert habe. Ansonsten kann ich einfach das andersherum sortieren lassen und nach außen hin ändert sich nix am Zugriff.

Zitat:

Zitat von DeddyH
Zitat:

Zitat von xZise
Oder muss jedesmal eine neue Compare-Methode erstellen? Einmal für Vorwärts und einmal für Rückwärts

Eine andere Möglichkeit ist mir persönlich nicht bekannt und sooo viel Aufwand ist das ja nicht.

Jain. Ich habe mindestens 4 Methoden die ich dann doppelt habe. Es ist zwar kaum Aufwand, aber das bläht doch alles etwas auf. Besonders, weil der Unterschied ja NUR ein Vorzeichen ist.

Naja schade.

MfG
xZise

Reinhard Kern 5. Aug 2009 17:58

Re: TList.Sort Rückwärts?
 
Zitat:

Zitat von xZise
Zitat:

Zitat von Die Muhkuh
Du kannst ja genau so gut vorwärts sortieren und rückwärts auslesen.

Sollte eigentlich kein Unterschied machen zu rückwärts sortieren und vorwärts auslesen.

Jain. Für das Ergebnis nicht, aber dann müsste ich speichern, wie rum ich sortiert habe.

Denkfehler: dann gerade nicht! (Du sortierst immer vorwärts - DAS kannst du dir hoffentlich merken. Beim Auslesen kannst du entscheiden ob vorwärts oder rückwärts).

Gruss Reinhard

himitsu 5. Aug 2009 18:09

Re: TList.Sort Rückwärts?
 
du kannst dir ja in der Liste (evtl. im Tag?) die Richtung speichern und die Vergleichsprozeduren werten das aus und kehren notfalls einfach ihr Ergebnis noch schnell um, bevor sie sich beenden.

xZise 5. Aug 2009 18:17

Re: TList.Sort Rückwärts?
 
Zitat:

Zitat von Reinhard Kern
Zitat:

Zitat von xZise
Zitat:

Zitat von Die Muhkuh
Du kannst ja genau so gut vorwärts sortieren und rückwärts auslesen.

Sollte eigentlich kein Unterschied machen zu rückwärts sortieren und vorwärts auslesen.

Jain. Für das Ergebnis nicht, aber dann müsste ich speichern, wie rum ich sortiert habe.

Denkfehler: dann gerade nicht! (Du sortierst immer vorwärts - DAS kannst du dir hoffentlich merken. Beim Auslesen kannst du entscheiden ob vorwärts oder rückwärts).

Gruss Reinhard

Ehrm wo ist der Denkfehler? In den Einstellungen steht, dass nicht der neueste sondern älteste Eintrag genutzt werden soll. Also was mache ich:
Delphi-Quellcode:
Sort(<Datumsvergleichsfunktion>, Rückwärts)
Das wars. Danach ist es mir egal, ob der neueste oder älteste Eintrag zuerst kommt. Ansonten müsste ich JEDESMAL wenn ich auf einen Eintrag zugreifen will:
Delphi-Quellcode:
if Rückwärts then
  Blabla := Items[Count - 1]
else
  Blabla := Items[0];
Zitat:

Zitat von himitsu
du kannst dir ja in der Liste (evtl. im Tag?) die Richtung speichern und die Vergleichsprozeduren werten das aus und kehren notfalls einfach ihr Ergebnis noch schnell um, bevor sie sich beenden.

Naja TList hat kein Tag hat die schonmal nicht. Aber das "Problem" ist auch, dass dann die Einträge die Liste kennen müssen, weil dummerweise kann man keine Funktionen von Klassen benutzen.

MfG
xZise

himitsu 5. Aug 2009 18:28

Re: TList.Sort Rückwärts?
 
OK, dann ist das 'ne blöde Idee ... dachte die bekommt mit, welche TList zu den Einträgen gehört
Zitat:

(ist schon blöd, wenn die OH nicht läuft man da nicht mal nachsehn kann und auf die Idee mal in D7 zu gucken war ich och nicht gekommen :oops: )
aber dann bleibt dir wohl nichts anderes Übrig, als da noch weitere Sortierprozeduren zu erstellen
(eine "lobale" Gloabel variable, wo du extern die Richtung speicherst und das in den Prozeduren abfragst, wäre nicht so gut ... man hätte da zumindestens noch einen weiteren Parameter mit in die Funktion einbauen können, wo man dann noch zusätzliche infost übermitteln kann)

PS: oder du sortierst erstmal die Liste
und sortierst diese danach dann nochmal um, wenn es wückwärst ist :nerd:
Delphi-Quellcode:
Liste.Sort(...);
if Rückwärts then
  for i := 0 to Liste.Count div 2 - 1 do begin
    P := Liste.Items[i];
    Liste.Items[i] := Liste.Items[Liste.Count - i];
    Liste.Items[Liste.Count - i] := P;
  end;

xZise 5. Aug 2009 18:40

Re: TList.Sort Rückwärts?
 
Zitat:

Zitat von himitsu
OK, dann ist das 'ne blöde Idee ... dachte die bekommt mit, welche TList zu den Einträgen gehört
Zitat:

(ist schon blöd, wenn die OH nicht läuft man da nicht mal nachsehn kann und auf die Idee mal in D7 zu gucken war ich och nicht gekommen :oops: )
aber dann bleibt dir wohl nichts anderes Übrig, als da noch weitere Sortierprozeduren zu erstellen
(eine "lobale" Gloabel variable, wo du extern die Richtung speicherst und das in den Prozeduren abfragst, wäre nicht so gut ... man hätte da zumindestens noch einen weiteren Parameter mit in die Funktion einbauen können, wo man dann noch zusätzliche infost übermitteln kann)

Ja genau ;) Das hatte ich auch nicht vor. Und joar, also .Sort ist an sich ganz genial gemacht, aber das ist "Verbesserungswürdig" (z.B. ein "of object" dürfte helfen ^^ Oder intern eine Rückwärtsfunktion, dass dies nicht im Vergleich entschieden werden muss).

Zitat:

Zitat von himitsu
PS: oder du sortierst erstmal die Liste
und sortierst diese danach dann nochmal um, wenn es wückwärst ist :nerd:
Delphi-Quellcode:
Liste.Sort(...);
if Rückwärts then
  for i := 0 to Liste.Count div 2 - 1 do begin
    P := Liste.Items[i];
    Liste.Items[i] := Liste.Items[Liste.Count - i];
    Liste.Items[Liste.Count - i] := P;
  end;

Jeha :mrgeen: , ich glaube ich bleibe bei zwei Methoden pro Typ.

MfG
xZise

Khabarakh 5. Aug 2009 18:52

Re: TList.Sort Rückwärts?
 
Zitat:

Zitat von xZise
Ich habe mindestens 4 Methoden die ich dann doppelt habe.

Äh, nicht wirklich :gruebel: . Im zweiten Comparer rufst du einfach den ersten mit vertauschten Argumenten auf - immer noch perfekt DRY.

Und wenn dir das immer noch zu viel Syntax-Gewurstel drum herum ist, dann nutze doch die anonymen Methoden von D2009: TList<T> im Zusammenspiel mit TDelegatedComparer<T>.

xZise 5. Aug 2009 19:52

Re: TList.Sort Rückwärts?
 
Zitat:

Zitat von Khabarakh
Zitat:

Zitat von xZise
Ich habe mindestens 4 Methoden die ich dann doppelt habe.

Äh, nicht wirklich :gruebel: . Im zweiten Comparer rufst du einfach den ersten mit vertauschten Argumenten auf - immer noch perfekt DRY.

Hmmmm also statt
Delphi-Quellcode:
function PublishedCompare(Item1, Item2: Pointer): Integer;
begin
  Result := CompareValue(TVersion(Item1).PublishedTime, TVersion(Item2).PublishedTime);
end;

function PublishedCompareB(Item1, Item2: Pointer): Integer;
begin
  Result := -CompareValue(TVersion(Item1).PublishedTime, TVersion(Item2).PublishedTime);
end;
soll ich
Delphi-Quellcode:
function PublishedCompare(Item1, Item2: Pointer): Integer;
begin
  Result := CompareValue(TVersion(Item1).PublishedTime, TVersion(Item2).PublishedTime);
end;

function PublishedCompareB(Item1, Item2: Pointer): Integer;
begin
  Result := PublishedCompare(Item2, Item1);
end;
aufrufen? Nicht wirklich "weniger"...

Am elegantesten wäre es direkt bei TList:
Delphi-Quellcode:
procedure QuickSort(SortList: PPointerList; L, R, F: Integer;
  SCompare: TListSortCompare);
var
  I, J: Integer;
  P, T: Pointer;
begin
  repeat
    I := L;
    J := R;
    P := SortList^[(L + R) shr 1];
    repeat
      while F*SCompare(SortList^[I], P) < 0 do
        Inc(I);
      while F*SCompare(SortList^[J], P) > 0 do
        Dec(J);
      if I <= J then
      begin
        if I <> J then
        begin
          T := SortList^[I];
          SortList^[I] := SortList^[J];
          SortList^[J] := T;
        end;
        Inc(I);
        Dec(J);
      end;
    until I > J;
    if L < J then
      QuickSort(SortList, L, J, SCompare);
    L := I;
  until I >= R;
end;

procedure TList.Sort(Compare: TListSortCompare; Backwards : Boolean = False);
var
  F : Integer;
begin
  if Backwards then
    F := -1
  else
    F := 1;
  if (FList <> nil) and (Count > 1) then
    QuickSort(FList, 0, Count - 1, F, Compare);
end;
Zitat:

Zitat von Khabarakh
Und wenn dir das immer noch zu viel Syntax-Gewurstel drum herum ist, dann nutze doch die anonymen Methoden von D2009: TList<T> im Zusammenspiel mit TDelegatedComparer<T>.

1. Wollte ich das auch abwärtskompatibel gestalten :)
2. Gibt es irgendwo ein Tut :P ?

MfG
xZise

Khabarakh 5. Aug 2009 21:22

Re: TList.Sort Rückwärts?
 
Zitat:

Zitat von xZise
Nicht wirklich "weniger"...

Darum ging's auch nicht :P , sondern wie gesagt um DRY. Duplizierte Logik ist schon deshalb schlimm, weil es einfach in fast allen Fällen ohne wirklichen Mehraufwand vermeidbar ist.
Zitat:

Zitat von xZise
2. Gibt es irgendwo ein Tut :P ?

Für Generics oder anonyme Methoden ;) ? Ich kann dir keines selbst empfehlen, aber bei Dr. Bob gibts beides.

xZise 5. Aug 2009 22:10

Re: TList.Sort Rückwärts?
 
Ahcso ich kannte "DRY" bisher noch nicht ;)

MfG
xZise

xZise 14. Aug 2009 13:02

Re: TList.Sort Rückwärts?
 
Moinsen, mir ist gerade eben was aufgefallen bei den Soßen von Classes.pas:
Delphi-Quellcode:
TStringListSortCompare = function(List: TStringList; Index1, Index2: Integer): Integer;
Warum warum warum gibt es das nicht für die TList? Auch erscheint es mir so als wäre TStringList/TStrings fast so wie TList nur mit zusätzlichen Stringoperationen...

MfG
xZise

Reinhard Kern 14. Aug 2009 15:50

Re: TList.Sort Rückwärts?
 
Zitat:

Zitat von xZise
Moinsen, mir ist gerade eben was aufgefallen bei den Soßen von Classes.pas:
Delphi-Quellcode:
TStringListSortCompare = function(List: TStringList; Index1, Index2: Integer): Integer;
Warum warum warum gibt es das nicht für die TList? Auch erscheint es mir so als wäre TStringList/TStrings fast so wie TList nur mit zusätzlichen Stringoperationen...

MfG
xZise

Hallo,

inwiefern würde das dein Problem lösen?

Und wieso leitest du dir nicht einfach eine Klasse TListEx ab und fügst der eine Methode SortReverse hinzu? Ist doch perfectly OO.

Gruss Reinhard

xZise 14. Aug 2009 16:25

Re: TList.Sort Rückwärts?
 
Moin,

es ging mir bei dem letzten Posting nur darum, dass Borland schon mal daran gedacht hat die Liste nach der sortiert wird mit zu übergeben. TList nämlich tut dies nicht. Das hat mich so ein bisschen enttäuscht, da der Code ja nicht von gestern ist. Sondern schon "uralt" und Borland nicht auf die Idee gekommen ist dies zu ändern.

MfG
xZise


Alle Zeitangaben in WEZ +1. Es ist jetzt 00:08 Uhr.

Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz