Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Object-Pascal / Delphi-Language (https://www.delphipraxis.net/32-object-pascal-delphi-language/)
-   -   StringList CustomSort (https://www.delphipraxis.net/197840-stringlist-customsort.html)

MicMic 10. Sep 2018 19:44

Delphi-Version: 10.2 Tokyo

StringList CustomSort
 
Hallo,

ich habe eine StringList und mit AddObject füge ich ein "Array Of Record" den Items hinzu.
Das geht alles.

Bei manchen Aktionen wird umsortiert, mittels CustomSort. Dabei soll das erste Item samt Object nicht immer umsortiert werden und bei Index 0 bleiben.
Kann man da irgendwie die CustomSort erweitern?
So schaut meine aus:
Code:
Function Sort1(List: TStringList; Index1, Index2: Integer): Integer;
Begin
 Result := 0;
 If Assigned(List) Then
 Begin
  If TMStringList(List).SortUp = 0
  Then Result := -AnsiCompareText(List[Index1],List[Index2])
  Else Result := AnsiCompareText(List[Index1],List[Index2])
 End;
End;
Man könnte auch nach dem sortieren die zuvor Index 0 (die vielleicht nach dem sortieren auf Index 12 steht <- als Beispiel) wieder auf Index 0 verschieben. Aber so etwas wie MoveObject habe ich nicht gefunden. Mit InsertObject kann ich ein Eintrag leicht auf Index 0 einfügen. Das wäre Möglich. Fragt sich dann nur, wie ich (um das Beispiel zu nehmen) Index 12 erst mal herauskopiere, lösche und dann die kopierten Daten wieder einfüge.

Experten kennen bestimmt ne leichte Lösung.

InsertObject nutze ich schon für etwas anderes. Das schaut bei mir so aus.
Code:
MeineStringListe.InsertObject(0,TRecordDaten[12].Text ,@TRecordDaten[12]);
Gruß
Michael

Zacherl 10. Sep 2018 19:54

AW: StringList CustomSort
 
Du könntest prüfen, ob
Delphi-Quellcode:
Index1
oder
Delphi-Quellcode:
Index2
gleich Null sind und dann je nach Index und Sortierreihenfolge immer -1 oder +1 zurückgeben.

MicMic 10. Sep 2018 20:11

AW: StringList CustomSort
 
Das mit der Sortierreihenfolge habe ich nicht ganz so verstanden wegen Index 0
Habe aber mal eben meine CustomSort erweitert.
Code:
Function Sort1(List: TStringList; Index1, Index2: Integer): Integer;
Begin
 Result := 0;
 If Assigned(List) Then
 Begin
  If TMStringList(List).SortUp = 0
  Then Result := -AnsiCompareText(List[Index1],List[Index2])
  Else Result := AnsiCompareText(List[Index1],List[Index2])
 End;
 // hinzugefügt
 if Index1 = 0 then Result := -1;
 if Index2 = 0 then Result := +1;
End;
So bleibt der erste Eintrag immer bei Index 0. Wenn das so bleibt, ist's ja super einfach :=) Also mal Dankeschön. Aber ich habe mal etwas probiert. Wenn ich für Index1 = 0 bei Result +1 und bei Index2 = 0 bei Result -1 angebe, gibt's ein Fehler "Listenindex außerhalb des gültigen Bereichs". Aber so wie oben geht es. Würde aber gerne wissen, warum andersrum ein Fehler kommt. Damit ich's halt verstehe mit diesem CustomSort.

Aber nun muss ich ins Bettchen :)
Aber mal super Dankeschön. Mal wieder einen Schritt weiter und kann nun schön träumen *lach

Michael

Zacherl 10. Sep 2018 20:27

AW: StringList CustomSort
 
Zitat:

Zitat von MicMic (Beitrag 1412887)
Das mit der Sortierreihenfolge habe ich nicht ganz so verstanden wegen Index 0

Achso, ja das war auch Blödsinn :stupid: So wie du es momentan hast, sollte es schon passen.

Zitat:

Zitat von MicMic (Beitrag 1412887)
Würde aber gerne wissen, warum andersrum ein Fehler kommt.

Puh kann dir so aus dem Kopf grade gar nicht sagen, was mit dem Ergebnis des Vergleichs im Folgenden dann passiert, wenn man
Delphi-Quellcode:
Sort()
aufruft. Wahrscheinlich wird irgendwie versucht das Element an Index -1 so setzen oder so.

haentschman 11. Sep 2018 05:52

AW: StringList CustomSort
 
Moin...8-)
Muß es eine TStringlist sein? Geht auch TList<string> mit dem entsprechendem Comparer?

Jumpy 11. Sep 2018 07:42

AW: StringList CustomSort
 
Zitat:

Zitat von MicMic (Beitrag 1412887)
Wenn ich für Index1 = 0 bei Result +1 und bei Index2 = 0 bei Result -1 angebe, gibt's ein Fehler "Listenindex außerhalb des gültigen Bereichs". Aber so wie oben geht es. Würde aber gerne wissen, warum andersrum ein Fehler kommt. Damit ich's halt verstehe mit diesem CustomSort.

Deine Sort1-Funktion ist ja nur die Vergleichsfunktion. Der Fehler dürfte aber in der eigentlichen Sortierfunktion geworfen werden, d.h. du müsstest dir diese mal im Konzert mit deiner Funktion anschauen, dann sollte es klar werden, denke ich.

MicMic 11. Sep 2018 18:25

AW: StringList CustomSort
 
Zitat:

Zitat von Jumpy (Beitrag 1412913)
Zitat:

Zitat von MicMic (Beitrag 1412887)
Wenn ich für Index1 = 0 bei Result +1 und bei Index2 = 0 bei Result -1 angebe, gibt's ein Fehler "Listenindex außerhalb des gültigen Bereichs". Aber so wie oben geht es. Würde aber gerne wissen, warum andersrum ein Fehler kommt. Damit ich's halt verstehe mit diesem CustomSort.

Deine Sort1-Funktion ist ja nur die Vergleichsfunktion. Der Fehler dürfte aber in der eigentlichen Sortierfunktion geworfen werden, d.h. du müsstest dir diese mal im Konzert mit deiner Funktion anschauen, dann sollte es klar werden, denke ich.

Bei "-AnsiCompareText(List[Index1],List[Index2])" hatte er den Fehler verursacht.

Ich habe jetzt jedenfalls gemerkt, dass in Index2 nie 0 ankommt, wenn zuvor "if Index1=0 then Result := -1;" angegeben wird. Also mit dieser einzigen Zeile scheint es zu gehen. Aber ich verstehe es noch nicht so ganz, da z.B. ein "if Index1=1 then Result := -1;" die Anwendung einfriert (Keine Rückmeldung). Das dürfte doch gar nicht passieren? Es kommt dann wohl mit "AnsiCompareText" in Konflikt. Die Funktion wird ja je nach Inhaltsgröße der StringList mehrmals aufgerufen.

Es geht jedenfalls so:
Code:
Function Sort1(List: TStringList; Index1, Index2: Integer): Integer;
Begin
 Result := 0;
 If Assigned(List) Then
 Begin
  If TMStringList(List).SortUp = 0
  Then Result := -AnsiCompareText(List[Index1],List[Index2])
  Else Result := AnsiCompareText(List[Index1],List[Index2])
 End;
 // hinzugefügt damit der erste Eintrag trotz CustomSort immer oben bleibt
 if Index1 = 0 then Result := -1;
End;
Aber ob's dann immer so passt? Die StringList hat ja nicht immer gleiche Inhalte. Und wie gesagt, prüfe ich "Index1 = 1" anstatt 0, macht die Anwendung Dauer-Urlaub. :)

@haentschman
Ich müsste wohl viel ändern im Source, wenn ich's in TList umbauen würde
Wollt das mit ner TStringList schon so behalten

Michael

freimatz 12. Sep 2018 11:23

AW: StringList CustomSort
 
Dann macht es halt der nächste und benötigt doppelt so lange - und ärgert sich dann über Dich.
Das Object zu nehmen war eine Notlösung als es noch keine Generics gab.
(und ich war schon so oft der "nächste)

Solutor 16. Sep 2018 10:28

AW: StringList CustomSort
 
Delphi-Quellcode:


Function Sort1(List: TStringList; Index1, Index2: Integer): Integer;
Begin
   Result:=0;            //Default Wert

   //========================================================
   //Der der Index 0 hat soll nach oben sortiert werden.  
   //========================================================
   If Index1=0 then
   begin
      Result:=-1;
      Exit;
   end;
   If Index2=0 then
   begin
      Result:=1;
      exit;
   end;


   //========================================================
   //Jetzt erst der Vergleich der eigentlichen Daten  
   //========================================================
   if AnsiCompareText(List[Index1],List[Index2])>0 then
   begin
      Result:=1;
      Exit;
   end;
   if AnsiCompareText(List[Index1],List[Index2])<0 then
   begin
      Result:=-1;
      Exit;
   end;
end;
Auf diese Weise kann man eine Sortierung nach verschiedenen Kriterien priorisieren.
Ähnlich wie man eine Excel Tabelle in einem Rutsch nach verschiedenen Spalten Sortieren kann.
Deswegen die strukturierte Schreibweise mit den "Exit" Befehlen.

Ich habs jetzt mal aus dem Gedächtnis geschrieben.
Muss man einfach mal debuggen und sehen was drin ist um die Results richtig rum zu setzen.

Die Geschwindigkeit finde ich Ausreichend. Ich sortiere so sehr große Records, in 5 Ebenen (Prioritäten)
Die Liste enthält 20000 Einträge und wird in einem Sekundenbruchteil sortiert.

himitsu 16. Sep 2018 11:07

AW: StringList CustomSort
 
Zitat:

Delphi-Quellcode:
   //========================================================
   //Jetzt erst der Vergleich der eigentlichen Daten
   //========================================================
   if AnsiCompareText(List[Index1],List[Index2])>0 then
   begin
      Result:=1;
      Exit;
   end;
   if AnsiCompareText(List[Index1],List[Index2])<0 then
   begin
      Result:=-1;
      Exit;
   end;

Delphi-Quellcode:
   //========================================================
   //Jetzt erst der Vergleich der eigentlichen Daten
   //========================================================
   Result := AnsiCompareText(List[Index1],List[Index2])

Delphi-Quellcode:
function Sort1(List: TStringList; Index1, Index2: Integer): Integer;
begin
  if Index1 = 0 then // Der der Index 0 hat soll nach oben sortiert werden.
    Result := -1
  else if Index2 = 0 then
    Result := 1
  else
    Result := AnsiCompareText(List[Index1], List[Index2]);
end;
:stupid:


Alle Zeitangaben in WEZ +1. Es ist jetzt 03:22 Uhr.

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