![]() |
AW: Dateinamen auslesen und sortieren
Zitat:
|
AW: Dateinamen auslesen und sortieren
Es handelt sich aber nicht um Dezimalzahlen mit Nachkommastellen, sondern um Nummerierungen, wie sie z. B. auch bei Word, OpenOffice ... üblich sind.
Kapitel 2.3 steht da auch vor Kapitel 2.12, allerdings steht Kapitel 2.30 hinter Kapitel 2.12, ist aber nicht identisch mit Kapitel 2.3. Im vorliegenden Fall fehlt bei den Zahlen nach dem Punkt genaugenommen die führende 0 und die Sortierung soll die fehlende 0 mit berücksichtigen. Die Punkte sind letztlich nur optische Trenner zwischen unterschiedlichen Zahlengruppen. Jede Zahlengruppe soll für sich aufsteigend sortiert werden. Und damit ist 3 < 12 und von daher 2.3 vor 2.12 einzusortieren. |
AW: Dateinamen auslesen und sortieren
Hallo zusammen,
ja, also Delphi.Narium hat es richtig erfasst und zusammengefasst. Es handelt sich tatsächlich um eine Struktur wie bei einer Kapitelnummerierung. Und dort ist die 2.3 vor der 2.12 zu finden. Anfangs habe ich überhaupt nicht daran gedacht, dass es hier ein Problem geben könnte, da die Dateien im Explorer in der korrekten Reihenfolge angezeigt werden. Umso überraschter bin ich jetzt, dass es mir so schwer fällt dafür eine einfache Lösung zu finden. Gibt es denn irgendwo eine Übersicht über die möglichen "Filter" von TCompareOptions? Dann würde ich da gern weiterlesen um zu verstehen, wo es klemmt und wie es besser geht. |
AW: Dateinamen auslesen und sortieren
|
AW: Dateinamen auslesen und sortieren
Zitat:
|
AW: Dateinamen auslesen und sortieren
Kannst du vielleicht damit anfangen? Hier habe ich kurz ein Beispiel ohne string.compare gebastelt. Das funktioniert bei mir im Delphi 2007.
Delphi-Quellcode:
function MySortCompare(List: TStringList; Index1, Index2: Integer): Integer;
var wStr1: WideString; wStr2: WideString; Flags: Dword; begin wStr1 := List[Index1]; wStr2 := List[Index2]; Flags := 9; // coDigitAsNumbers + coIgnoreCase Result := CompareStringW(LOCALE_USER_DEFAULT, Flags, PWideChar(wStr1), Length(wStr1), PWideChar(wStr2), Length(wStr2)) - CSTR_EQUAL; end; procedure Tf_Tester.TestCustomSort; var SL: TStringList; i: Integer; begin m_test.Clear; SL := TStringList.Create; try SL.Add('2.6.1.csv'); SL.Add('4.5.csv'); SL.Add('4.9.1.csv'); SL.Add('1.3.csv'); SL.Add('2.3.csv'); SL.Add('2.6.2.csv'); SL.Add('1.7.csv'); SL.Add('4.9.2.csv'); SL.Add('1.6.csv'); SL.Add('2.8.csv'); SL.Add('2.6.3.csv'); SL.Add('4.8.csv'); SL.Add('2.12.csv'); SL.CustomSort(@MySortCompare); for i := 0 to Pred(SL.Count) do begin m_test.Lines.Add(SL[i]); end; finally FreeAndNil(SL); end; end; Zitat:
|
AW: Dateinamen auslesen und sortieren
Delphi-Quellcode:
Warum sinnlos einen langsamen und vor allem unnötigen Speichermanager benutzen, inkl. einiger unnötig aufwändiger/langsamer String-Operationen? (Strings komplett umkopieren)
function MySortCompare(List: TStringList; Index1, Index2: Integer): Integer;
var Str1, Str2: string; // oder direkt List[...] benutzen Flags: Dword; begin Str1 := List[Index1]; Str2 := List[Index2]; Flags := 9; // coDigitAsNumbers + coIgnoreCase Result := CompareString(LOCALE_USER_DEFAULT, Flags, PChar(Str1), Length(Str1), PChar(Str2), Length(Str2)) - CSTR_EQUAL; end; WideString = nutzt den Speichermanager, bzw. eine API des OLEAuth (OLE32) UnicodeString = die Wide-Version des AnsiString AnsiString/UnicodeString/UTF8String/usw. sind LongStrings und verwenden auch eine Referenzzählung, sowie den Delphi-Speichermanager (aktuell FastMM) PS: Der Typ String[123] ist ein ShortString (nur der Vollständigkeit halber) ... sowie der Typ "String" im Delphi 1 und davor im Turbo Pascal. |
AW: Dateinamen auslesen und sortieren
Zitat:
|
AW: Dateinamen auslesen und sortieren
Wie wäre es hiermit? Getestet mit Delphi Alexandria um eine "logische" Sortierung zu implementieren, dabei ist dann das "Kapitel" da wo es sein sollte.
Delphi-Quellcode:
program Project1;
{$APPTYPE CONSOLE} {$R *.res} uses System.SysUtils, System.Classes; function StrCmpLogicalW(P1, P2: PWideChar): Integer; stdcall; external 'Shlwapi.dll' name 'StrCmpLogicalW'; function CompareProc(List: TStringList; Index1, Index2: Integer): Integer; begin Result := StrCmpLogicalW(PChar(List[Index1]), PChar(List[Index2])); end; var SL: TStringList; i: Integer; begin try SL := TStringList.Create; try SL.Add('2.6.1.csv'); SL.Add('4.5.csv'); SL.Add('4.9.1.csv'); SL.Add('1.3.csv'); SL.Add('2.3.csv'); SL.Add('2.6.2.csv'); SL.Add('1.7.csv'); SL.Add('4.9.2.csv'); SL.Add('1.6.csv'); SL.Add('2.8.csv'); SL.Add('2.6.3.csv'); SL.Add('4.8.csv'); SL.Add('2.12.csv'); SL.CustomSort(@CompareProc); for i := 0 to Pred(SL.Count) do WriteLn(SL[i]); finally SL.Free; end; ReadLn; except on E: Exception do Writeln(E.ClassName, ': ', E.Message); end; end. Zitat:
|
AW: Dateinamen auslesen und sortieren
Am Ende ist das doch alles das gleiche, oder was denkt ihr was die Delphi Methode intern macht?
Das Problem liegt offenbar woanders. |
Alle Zeitangaben in WEZ +1. Es ist jetzt 04:00 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