AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Thema durchsuchen
Ansicht
Themen-Optionen

TStringList.Sort

Ein Thema von H.Bothur · begonnen am 30. Sep 2023 · letzter Beitrag vom 1. Okt 2023
Antwort Antwort
H.Bothur

Registriert seit: 25. Jun 2012
Ort: Seevetal & Lagos
257 Beiträge
 
Delphi 11 Alexandria
 
#1

TStringList.Sort

  Alt 30. Sep 2023, 18:00
Moin,

ich stehe gerade ein bisschen auf dem Schlauch, ich habe eine TStringList mit folgendem Inhalt (gekürzt):

Delphi-Quellcode:
0002 F: ADDAMS_FAMILY Titel D1-03.avi
0003 F: ADDAMS_FAMILY Titel D1-04.avi
0004 F: ADDAMS_FAMILY Titel D1-05.avi
0005 F: ADDAMS_FAMILY Titel D1-06.avi
0006 F: ADDAMS_FAMILY Titel D1-07.avi
0007 F: ADDAMS_FAMILY Titel D1-08.avi
0008 F: ADDAMS_FAMILY Titel D1-09.avi
0009 F: ADDAMS_FAMILY Titel D1-10.avi
0011 F: Akte Ex-1-1_ Endlich Prinzessin (S01_E01).mp4
0012 F: Akte Ex-1-2_ Mord am Weinberg (S01_E02).mp4
0013 F: Akte Ex-1-3_ Der fröhliche Mönch (S01_E03).mp4
0014 F: Akte Ex-1-4_ Im Rausch der Ermittlungen (S01_E04).mp4
0015 F: Akte Ex-1-5_ Schweinkram (S01_E05).mp4
0016 F: Akte Ex-1-6_ Fernweh (S01_E06).mp4
0017 F: Akte Ex-1-7_ Ommm (S01_E07).mp4
0018 F: Akte Ex-1-8_ Die Prophezeiung (S01_E08).mp4
0019 F: Akte Ex-2-1_ Treu bis ins Grab (S02_E01).mp4
0020 F: Akte Ex-2-2_ Ohne Spritze (S02_E02).mp4
0001 S: Addams Family
0010 S: Akte Ex
Wenn ich jetzt die Liste über StringList.sort sortiere hätte ich erwartet das die beiden letzten Zeilen entsprechend einsortiert werden - werden die aber komischerweise nicht sondern leiben unten stehen.

Warum bzw. wo denke ich falsch ?

Hans
Hans-Georg Bothur
www.hermann-juergensen.de
  Mit Zitat antworten Zitat
Benutzerbild von himitsu
himitsu

Registriert seit: 11. Okt 2003
Ort: Elbflorenz
44.062 Beiträge
 
Delphi 12 Athens
 
#2

AW: TStringList.Sort

  Alt 30. Sep 2023, 18:26
Da wir nicht sehen wie du es machst ... keine Ahnung.

Grundsätzlich funktioniert es.
Abgesehn, der Text wäre nicht wirklich genau der, welchen du hier zeigst. (nicht sichtbare Zeichen, die Ziffern nicht wirklich DIESE Ziffern, sondern andere Unicodezeichen usw.)
Neuste Erkenntnis:
Seit Pos einen dritten Parameter hat,
wird PoSex im Delphi viel seltener praktiziert.
  Mit Zitat antworten Zitat
H.Bothur

Registriert seit: 25. Jun 2012
Ort: Seevetal & Lagos
257 Beiträge
 
Delphi 11 Alexandria
 
#3

AW: TStringList.Sort

  Alt 30. Sep 2023, 18:42
Hier der komplette Source:

Delphi-Quellcode:
unit SerienDatabase;

interface

uses
  Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
  Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.StdCtrls, Vcl.ComCtrls, Vcl.ExtCtrls;

type
  TSerienDB = class(TForm)
    BtnPlay: TButton;
    BtnLaden: TButton;
    LbEVerzeichnis: TLabeledEdit;
    Memo1: TMemo;
    procedure BtnLadenClick(Sender: TObject);
  private
    { Private-Deklarationen }
  public
    { Public-Deklarationen }
  end;

var
  SerienDB: TSerienDB;
  LfdNummer: Integer;

implementation

{$R *.dfm}

procedure FindAllFiles(RootFolder: string; Mask: string = '*.*'; Recurse: Boolean = True);
var
  SR: TSearchRec;
  DateiListe: TStringList;
begin
  RootFolder := IncludeTrailingPathDelimiter(RootFolder);
  DateiListe := TStringList.Create;
  DateiListe.Sorted := true;

  if Recurse then
    if FindFirst(RootFolder + '*.*', faAnyFile, SR) = 0 then
      try
        repeat
          if SR.Attr and faDirectory = faDirectory then
            // --> ein Verzeichnis wurde gefunden
            if (SR.Name <> '.') and (SR.Name <> '..') then
            begin
              (* Verzeichnis gefunden *)
              DateiListe.Add(Format('%.*d', [4, LfdNummer]) +' S: ' +SR.Name);
              LfdNummer := LfdNummer +1;
              FindAllFiles(RootFolder + SR.Name, Mask, Recurse);
            end;
        until FindNext(SR) <> 0;
      finally
        FindClose(SR);
      end;
  if FindFirst(RootFolder + Mask, faAnyFile, SR) = 0 then
    try
      repeat
        if SR.Attr and faDirectory <> faDirectory then
        begin
          // --> eine Datei wurde gefunden
          DateiListe.Add(Format('%.*d', [4, LfdNummer]) +' F: ' +SR.Name);
          LfdNummer := LfdNummer +1;
        end;
      until FindNext(SR) <> 0;
    finally
      FindClose(SR);
    end;
    Dateiliste.Sort;
    SerienDB.Memo1.Lines.AddStrings(DateiListe);
    DateiListe.Free;
end;

procedure TSerienDB.BtnLadenClick(Sender: TObject);
begin
  LfdNummer := 1;
  FindAllFiles(LbEVerzeichnis.Text);
end;

end.
Der Sort kommt bevor ich die StringList an das Memo zur Anzeige übergebe - es wird nur nicht sortiert. Oder - blöde gefrafg, muss ich generell die Sortierfunktion selber dazuschreiben ? Ich hätte gedacht das es so eine normale Ascii-Sortierung geben sollte.

Hans
Hans-Georg Bothur
www.hermann-juergensen.de
  Mit Zitat antworten Zitat
Benutzerbild von Uwe Raabe
Uwe Raabe

Registriert seit: 20. Jan 2006
Ort: Lübbecke
11.452 Beiträge
 
Delphi 12 Athens
 
#4

AW: TStringList.Sort

  Alt 30. Sep 2023, 20:54
Lass mal das DateiListe.Sorted := true; weg oder füge ein DateiListe.Duplicates := dupIgnore davor ein.
Uwe Raabe
Certified Delphi Master Developer
Embarcadero MVP
Blog: The Art of Delphi Programming
  Mit Zitat antworten Zitat
Benutzerbild von himitsu
himitsu

Registriert seit: 11. Okt 2003
Ort: Elbflorenz
44.062 Beiträge
 
Delphi 12 Athens
 
#5

AW: TStringList.Sort

  Alt 30. Sep 2023, 21:28
Da jeweils nur ein Verzeichnis in sich sortiert wird...

Kann es sein, dass die beiden Letzten in einem anderen Verzeichnis liegen?
Sag ja.

Weißt du was ein Debugger ist?
Haltepunkt auf SerienDB.Memo1.Lines.AddStrings und "nicht" wundern, warum das zwei Mal aufgerufen wird.


UND
Warum ist LfdNummer eine globale Variable?
Warum ist FindAllFiles keine Methode von von TSerienDB? (die würde schön ins private passen)
Warum ...

PS: Delphi-Referenz durchsuchenTDirectory.GetFiles
Neuste Erkenntnis:
Seit Pos einen dritten Parameter hat,
wird PoSex im Delphi viel seltener praktiziert.

Geändert von himitsu (30. Sep 2023 um 22:05 Uhr)
  Mit Zitat antworten Zitat
H.Bothur

Registriert seit: 25. Jun 2012
Ort: Seevetal & Lagos
257 Beiträge
 
Delphi 11 Alexandria
 
#6

AW: TStringList.Sort

  Alt 30. Sep 2023, 22:35
Lass mal das DateiListe.Sorted := true; weg oder füge ein DateiListe.Duplicates := dupIgnore davor ein.
Ich hab das DateiListe.Sorted := true; rausgenommen - ändert leider nichts

Hans
Hans-Georg Bothur
www.hermann-juergensen.de
  Mit Zitat antworten Zitat
H.Bothur

Registriert seit: 25. Jun 2012
Ort: Seevetal & Lagos
257 Beiträge
 
Delphi 11 Alexandria
 
#7

AW: TStringList.Sort

  Alt 30. Sep 2023, 22:43
Da jeweils nur ein Verzeichnis in sich sortiert wird...

Kann es sein, dass die beiden Letzten in einem anderen Verzeichnis liegen?
Sag ja.
Nein die beiden letzten sind die Verzeichnisse in denen die anderen Dateien liegen.

Zitat:
Weißt du was ein Debugger ist?
Haltepunkt auf SerienDB.Memo1.Lines.AddStrings und "nicht" wundern, warum das zwei Mal aufgerufen wird.
Ja - aber alle Zeilen sind trotzdem nur einmal in dem Memo - ich habe aber mal die Dateiliste als gloibale Variable genommen (ja - pfui) und die BtnClick verändert:

Delphi-Quellcode:
procedure TSerienDB.BtnLadenClick(Sender: TObject);
begin
  LfdNummer := 1;
  DateiListe := TStringList.Create;
  FindAllFiles(LbEVerzeichnis.Text);
  Dateiliste.Sort;
  SerienDB.Memo1.Lines.AddStrings(DateiListe);
  DateiListe.Free;
end;
Dann kommt das spannenderweise passend raus

Zitat:
UND
Warum ist LfdNummer eine globale Variable?
Weil ich nicht wusste wie ich das am besten mache wenn ich die procedure rekursiv aufrufe

Zitat:
Warum ist FindAllFiles keine Methode von von TSerienDB? (die würde schön ins private passen)
Warum ...
Weil ich immer noch nicht das Konzept mit den Methoden und so verstanden habe - sorry, da hänge ich halt immer noch in den 80ern bei TP3.0

Zitat:
Oh, das kannte ich nicht, das kucke ich mir morgen mal an !

Gruss
Hans
Hans-Georg Bothur
www.hermann-juergensen.de
  Mit Zitat antworten Zitat
Benutzerbild von Uwe Raabe
Uwe Raabe

Registriert seit: 20. Jan 2006
Ort: Lübbecke
11.452 Beiträge
 
Delphi 12 Athens
 
#8

AW: TStringList.Sort

  Alt 30. Sep 2023, 22:58
Beim rekursiven Aufruf von FindAllFiles wird aber jedes mal eine eigene DateiListe gefüllt und am Ende in das Memo übertragen. Das Sort wirkt dann halt auch nur auf die gerade aktuelle Instanz. Du solltest die DateiListe als Parameter an FindAllFiles übergeben und das Sort wie auch das Übertragen ins Memo außerhalb (also z.B. in BtnLadenClick) machen.
Uwe Raabe
Certified Delphi Master Developer
Embarcadero MVP
Blog: The Art of Delphi Programming
  Mit Zitat antworten Zitat
mytbo

Registriert seit: 8. Jan 2007
472 Beiträge
 
#9

AW: TStringList.Sort

  Alt 1. Okt 2023, 00:05
Hier der komplette Source: ...
Der Sort kommt bevor ich die StringList an das Memo zur Anzeige übergebe - es wird nur nicht sortiert.
Trenne Dateisuche/Datensammlung und Formatierung. Wenn ich deinen Quelltext richtig verstanden habe, möchtest du Folgendes (ohne Sortierung):
Delphi-Quellcode:
function FindPlayFiles(pmFileList: TStringList; const pmcPath: String; const pmcSearchMask: String = '*'; pmWithSubDirs: Boolean = True): Boolean;
const
  SEARCH_OPTION: array[Boolean] of TSearchOption = (TSearchOption.soTopDirectoryOnly, TSearchOption.soAllDirectories);
begin
  Result := False;
  if pmFileList = Nil then Exit; //=>
  if not TDirectory.Exists(pmcPath) then Exit; //=>

  var files: TStringDynArray := TDirectory.GetFiles(pmcPath, pmcSearchMask, SEARCH_OPTION[pmWithSubDirs]);
  if Length(files) > 0 then
  begin
    pmFileList.Clear;
    pmFileList.AddStrings(files);
    Result := True;
  end;
end;

procedure FormatPlayList(pmFmtList: TStrings; const pmcRootDir: String; pmFileList: TStringList; pmStartNumber: Integer = 1);
begin
  if pmFmtList = Nil then Exit; //=>
  if pmFileList = Nil then Exit; //=>
  if pmFileList.Count = 0 then Exit; //=>
  
  pmFmtList.BeginUpdate;
  try
    var run, currentDir: String;
    for var i: Integer := 0 to pmFileList.Count - 1 do
    begin
      run := TPath.GetDirectoryName(pmFileList[i]);
      if currentDir <> run then
      begin
        currentDir := run;
        pmFmtList.AddObject(Format('%.4d S: %s', [pmStartNumber, currentDir.Substring(Length(pmcRootDir))]), TObject(-1));
        Inc(pmStartNumber);
      end;

      pmFmtList.AddObject(Format('%.4d F: %s', [pmStartNumber, TPath.GetFileName(pmFileList[i])]), TObject(i));
      Inc(pmStartNumber);
    end;
  finally
    pmFmtList.EndUpdate;
  end;
end;

begin
  SerienDB.Memo.Lines.Clear;
  if FindPlayFiles(FFileList, FRootDir) then
    FormatPlayList(SerienDB.Memo.Lines, FRootDir, FFileList);
Disclaimer: Der Entwurf ist nur eine Überarbeitung des Originals.

Bis bald...
Thomas

Geändert von mytbo ( 1. Okt 2023 um 00:31 Uhr) Grund: Tippfehler korrigiert
  Mit Zitat antworten Zitat
Benutzerbild von himitsu
himitsu

Registriert seit: 11. Okt 2003
Ort: Elbflorenz
44.062 Beiträge
 
Delphi 12 Athens
 
#10

AW: TStringList.Sort

  Alt 1. Okt 2023, 00:45
Da die Daten bereits sortiert erstellt werden, ist ein nochmaliges Sortieren nutzlos,
und da es bereits eine übergreifende/lobale Komponente gibt, kann man sie auch direkt verwenden,
...
also einfach direkt ins Memo einfügen.

Ja, ein Memo ist langsam, aber
* wieviele Zeilen werden es denn? (keine 10-tausende und mehr, oder?)
* und Delphi-Referenz durchsuchenTStrings.BeginUpdate



Ja, als Parameter die Liste durchreichen

oder die Listen als Result rausgeben (für ein einfacheres Speichermanagement als String-Array, anstatt als Listen-Komponente)
und schon kann man das Ergebnis in die Liste des Aufrufers einfügen/übernehmen.
Neuste Erkenntnis:
Seit Pos einen dritten Parameter hat,
wird PoSex im Delphi viel seltener praktiziert.

Geändert von himitsu ( 1. Okt 2023 um 01:00 Uhr)
  Mit Zitat antworten Zitat
Antwort Antwort


Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 09:17 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