Delphi-PRAXiS
Seite 1 von 2  1 2      

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Algorithmen, Datenstrukturen und Klassendesign (https://www.delphipraxis.net/78-algorithmen-datenstrukturen-und-klassendesign/)
-   -   Stringlist nach Datum sortieren (https://www.delphipraxis.net/196608-stringlist-nach-datum-sortieren.html)

MicMic 3. Jun 2018 21:19

Stringlist nach Datum sortieren
 
Hallo,
ich habe hier schon so manche Routine gesehen, wie man das macht, mit diesem CustomSort.
Hat echt gedauert bis ich meine Daten/Variablen so umgebaut habe bis ich das auch nutzen kann.
Dann auch noch "Pointer" Zeugs. Habe ich ja sonst immer gemieden. *lach

Bei mir schaut es jedenfalls jetzt so aus, für eine CustomSort Function.

Code:
Function SortByDate(List: TStringList; Index1, Index2: Integer): Integer;
Begin
   Result := 0;
   If Assigned(List) Then
   Begin
      If (Trunc(TFDListRecord(Pointer(List.Objects[Index1])^).Time*24*60*60*1000) < Trunc(TFDListRecord(Pointer(List.Objects[Index2])^).Time*24*60*60*1000)) Then
      Begin
         If fjSortUp = 0 Then Result := 1 Else Result := -1;
      End Else
      If (Trunc(TFDListRecord(Pointer(List.Objects[Index1])^).Time*24*60*60*1000) > Trunc(TFDListRecord(Pointer(List.Objects[Index2])^).Time*24*60*60*1000)) Then
      Begin
         If fjSortUp = 0 Then Result := -1 Else Result := 1;
      End Else
      If (List[Index1] < List[Index2]) Then
      Begin
         If fjSortUp = 0 Then Result := 1 Else Result := -1;
      End Else
      If (List[Index1] > List[Index2]) Then
      Begin
         If fjSortUp = 0 Then Result := -1 Else Result := 1;
      End;
   End;
End;
Abgesehen von einer Optimierung, wollte ich mal fragen ob dies mit dem 24*60*60*1000 richtig ist? Dies ist in vielen Beispielen nicht angegeben. Die Sortierung ist so jedenfalls genauer aber anders wie z.B. von Total-Commander (nachfolgend TC genannt). Die Zeit kommt von TSearchRec.TimeStamp (TDateTime). Übrigens hat TC zum Windows Explorer (Win10) auch ein paar Unterschiede für die Datums-Sortierung. Ich habe zum Testen das Verzeichnis "C:\Windows\WinSxS" genommen. Dort existieren viele Verzeichnisse mit einer gleichen Zeitangabe. Die Unterschiede der Sortierung ergeben sich wohl durch gleiche Zeitangaben bis in die Millisekunden. Es kommt dann wohl drauf an, wie der TC oder der Win-Explorer weiter sortiert. In meiner Routine prüfe ich ja (im Falle von Result = 0 bei den ersten beiden IF-Abfragen) noch den Dateinamen. Bei mir gibt's im Kopf gerade so viel Input... ich kann gar nicht mehr richtig denken :) aber vieles versteh ich sowieso nicht.

Aber wie man eine richtige Sortierung macht, würde ich schon gerne lernen. Wobei... was ist richtig? TC oder Win-Explorer? Ich denke mal, in Windows stecken mehr Fehler drin, als im TC :)

Gruß
Michael

juergen 3. Jun 2018 21:58

AW: Stringlist nach Datum sortieren
 
Hallo,

ich habe sowas auch schon mal umgesetzt. Auch aus Performancegründen habe ich mir das Datum dabei im Format YYYYMMDD... (als Integer) in der Object-ID der StringList jeweils weggespeichert (die weiterer Nutzung der Uhrzeiten legt die Genauigkeit fest wie die Sortierung sein soll).
Wie die Anzeige für den User sein soll kannst du dann selbst festlegen. Sortiert wird aber nach der Object-ID der einzelnen Zeilen der StringList.

KodeZwerg 3. Jun 2018 22:00

AW: Stringlist nach Datum sortieren
 
Ich mach es ähnlich wie hier beschrieben. Relativ direkte Methode, ich bin sehr Zufrieden so.

edit
Ich beziehe mich auf das:
Delphi-Quellcode:
{$APPTYPE CONSOLE}

uses
  SysUtils,
  Classes,
  DateUtils;

function CompareDate(List: TStringList; Index1, Index2: Integer): Integer;
var
  Val1, Val2: TDateTime;
begin
  val1:= FileDateToDateTime(FileAge(list[Index1]));
  val2:= FileDateToDateTime(FileAge(list[Index2]));
  Result := CompareDateTime(Val1, Val2);
end;

var
  sl : TStringList;
  i : Integer;
begin
  sl := TStringList.Create();

  sl.Add('New Text Document (3).txt');
  sl.Add('New Text Document (2).txt');
  sl.Add('New Text Document.txt');

  sl.CustomSort(CompareDate);

  for i := 0 to sl.Count - 1 do
  begin
    Writeln(sl[i]);
  end;
end.

MicMic 3. Jun 2018 23:54

AW: Stringlist nach Datum sortieren
 
Ob FileAge hier für die Geschwindigkeit gut ist? Ich glaube nicht.
und FileDateToDateTime prüft hier wohl auch nur das Datum und nicht eine Uhrzeit? Zumindest wenn ich es richtig verstehe. FileDateToDateTime=32 Bit. Double=64 Bit?

Ich habe jedenfalls eben noch herausgefunden, dass meine 2 letzten IF-Abfragen nicht funktionieren. Hier soll ja ein Dateiname (TSearchrec.Name) sortiert werden, wenn bei Datum für Result 0 rauskommt. Also habe ich die letzten beiden IFs mal abgeändert:
Code:
If fjSortUp = 0 Then Result := -AnsiCompareText(List[Index1],List[Index2])
Else Result := AnsiCompareText(List[Index1],List[Index2])
So funktioniert dann auch die Sortierung mit den Dateinamen. Jedoch gibt es dennoch unterschiede zum TC. Es kommt halt darauf an, was der TC macht, wenn der Datumsvergleich bei gleichen Zeiten für Dateien oder Verzeichnisse 0 ergibt. Ich dachte evtl. das hier noch zusätzlich (wenn Result 0 ergibt) andere Datumsquellen genutzt werden (z.B. ein Erstellungsdatum). Aber in dem Verzeichnis wo ich das alles teste, haben die anderen Datumsquellen gleiche Angaben zum normalen Änderungsdatum.

Die Geschichte geht ja dann auch weiter. Zum Beispiel beim Sortieren der Dateigröße. Dort hat man auch gleiche Dateigrößen in einem Verzeichnis. Also muss man sich doch gut überlegen, was man macht, wenn ein Datum oder eine Dateigröße gleich ist. Oder soll man wenn Index1 < Index2 oder Index1 > Index2 den Wert 0 zurück liefert, weitere Prüfungen auslassen und damit Leben?

Vielleicht könnte noch jemand etwas zu diesem ...Time*24*60*60*1000 schreiben, ob dies so richtig ist.

Michael

MicMic 4. Jun 2018 08:06

AW: Stringlist nach Datum sortieren
 
Ich habe nun herausgefunden wie der TC bei Datum sortiert.
Also entweder auf oder absteigend und wenn ein Datum+Zeit gleich ist, wird nach Dateinamen sortiert aber hier dann nur immer in einer Richtung.

Wie es der Win-Explorer macht, weiß ich noch nicht :)

Michael

Jumpy 4. Jun 2018 08:13

AW: Stringlist nach Datum sortieren
 
Evtl. ist es aber auch von der vorherigen Sortierung abhängig? Also es wird z.B erst nach Name sortiert. Dann wird auf das Datum geklickt um nach dem Datum zu sortieren und je nach Sortieralgo, bleibt die vorherige Namessortierung dabei erhalten oder nicht. Stichwort ist glaub ich Stabilität?

p80286 4. Jun 2018 11:50

AW: Stringlist nach Datum sortieren
 
"Stabilität" ist korrekt.
ist ein Algo. "stabil", dann behält er die vorgefundene Reihenfolge bei, wenn beide Vergleichsfelder/Werte gleich sind.
Was das Filedate angeht, wenn ich mich recht erinnere liegt die Auflösung bei 2 sec. Zumindest unter DOS bzw FAT war es so.

Gruß
K-H

MicMic 4. Jun 2018 12:57

AW: Stringlist nach Datum sortieren
 
Eine vorherige Sortierung zu berücksichtigen würde Sinn machen.
Aber der Win-Explorer oder der TC macht das auch nicht.

Man könnte dann aber wirklich auch Sinn hineingeben, dass man von einer Standard-Sortierung ausgeht (Also nach Alphabet der Dateinamen), wenn Datumsvergleiche (+Zeit) wegen gleichen Datumsangaben (+Zeit) fehlschlagen. So werde ich das dann auch lassen und bei der Sortierung der Dateigröße ebenfalls so handeln.

Michael

KodeZwerg 4. Jun 2018 17:14

AW: Stringlist nach Datum sortieren
 
ich hab was überlesen, sorry, Beitrag entfernt.

himitsu 4. Jun 2018 17:19

AW: Stringlist nach Datum sortieren
 
Man kann auch nach mehreren Kriteien sortieren und bekommt so ebenfalls ein eindeutiges Ergebnis.
Ob da nun stabil sortiert wird oder nicht, ist dabei egal, da Beide das selbe Ergebnis liefern.

z.B. als letztes der Dateiname, welcher bekanntlich eindeutig ist und somit auch nur "eine" Reihenfolge zulässt.


Alle Zeitangaben in WEZ +1. Es ist jetzt 23:39 Uhr.
Seite 1 von 2  1 2      

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