AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Programmierung allgemein Algorithmen, Datenstrukturen und Klassendesign Delphi Sortierfunktion nach Datum in einer TStringList
Thema durchsuchen
Ansicht
Themen-Optionen

Sortierfunktion nach Datum in einer TStringList

Ein Thema von juergen · begonnen am 3. Jul 2015 · letzter Beitrag vom 4. Jul 2015
Antwort Antwort
Seite 1 von 2  1 2      
Benutzerbild von juergen
juergen

Registriert seit: 10. Jan 2005
Ort: Bönen
1.164 Beiträge
 
Delphi 11 Alexandria
 
#1

Sortierfunktion nach Datum in einer TStringList

  Alt 3. Jul 2015, 18:08
Hallo zusammen,

ich hatte bisher beim Einlesen von Dateien in eine StringList das Datum der jeweiligen Datei als Integerwert in das jeweilige Object der StringList gespeichert und konnte die StringList somit gut nach Datum sortieren. Wenn Dateien das gleiche Datum hatten, wurde dann nach Dateiname sortiert
Delphi-Quellcode:
  function DoCompareByDate(List: TStringList; Index1, Index2: Integer): Integer;
  begin
    Result := 0;
    if Assigned(List) then begin
      if (Integer(List.Objects[Index1]) < Integer(List.Objects[Index2])) then begin
        Result := 1;
      end
      else if (Integer(List.Objects[Index1]) > Integer(List.Objects[Index2])) then begin
        Result := -1;
      end;
    end;
  end;

Nun kann ich das Datum nicht mehr als Object in der StringList speichern, da was anderes dafür vorgesehen ist.
Meine derzeitiges Konzept:
Damit ich weiterhin auch nach Datum sortieren kann, würde ich beim Einlesen der Dateien eine *zweite, neue* Stringlist füllen, welche dieselbe Object-ID erhält wie die "Master"-StringList. In der zweiten Stringlist würde ich dann nur das Datum speichern.
Meine Datumssortierfunktion könnte dann auf diese 2. Liste angewendet werden.

Meine Fragen:
- Wie bekomme ich die "Master" Stringlist so sortiert wie die Datums-StringList (beide Object-Ids sind ja gleich)?
- Gibt es evtl. alternative Konzept-Vorschläge?

Edit: Eine Umstellung der vorhandenen Master-TStringList auf z.B. TObjectList würde ich nur sehr, sehr ungern vornehmen...


Vielen Dank schon mal im Voraus!
Jürgen
Indes sie forschten, röntgten, filmten, funkten, entstand von selbst die köstlichste Erfindung: der Umweg als die kürzeste Verbindung zwischen zwei Punkten. (Erich Kästner)
  Mit Zitat antworten Zitat
Benutzerbild von DeddyH
DeddyH

Registriert seit: 17. Sep 2006
Ort: Barchfeld
27.537 Beiträge
 
Delphi 11 Alexandria
 
#2

AW: Sortierfunktion nach Datum in einer TStringList

  Alt 3. Jul 2015, 18:39
Wieso erstellst Du nicht eine Klasse, die alle benötigten Daten enthält, und hinterlegst diese dann in der Objects-Eigenschaft? Dafür ist diese ja auch eigentlich vorgesehen, Du musst nur daran denken, diese beim Löschen eines Eintrags auch wieder freizugeben bzw. freigeben zu lassen.
Detlef
"Ich habe Angst vor dem Tag, an dem die Technologie unsere menschlichen Interaktionen übertrumpft. Die Welt wird eine Generation von Idioten bekommen." (Albert Einstein)
Dieser Tag ist längst gekommen
  Mit Zitat antworten Zitat
Benutzerbild von Dalai
Dalai

Registriert seit: 9. Apr 2006
1.680 Beiträge
 
Delphi 5 Professional
 
#3

AW: Sortierfunktion nach Datum in einer TStringList

  Alt 3. Jul 2015, 19:03
Alternativ kann man auch eine neue von TStringList abgeleitete Klasse erstellen, die die nötigen Attribute enthält, und diese statt der TStringList nutzen.

MfG Dalai
  Mit Zitat antworten Zitat
Benutzerbild von juergen
juergen

Registriert seit: 10. Jan 2005
Ort: Bönen
1.164 Beiträge
 
Delphi 11 Alexandria
 
#4

AW: Sortierung einer "Master"-TStringList nach der Reihenfolge einer 2. TStringList

  Alt 3. Jul 2015, 20:01
Hallo,

danke für die Antworten. In einem neuen Projekt würde ich in diesem Fall mit Objekten arbeiten, auch wenn ich mich momentan damit noch nicht so auskenne.
Da aber schon viele Anpassungen meiner jetzigen TStringList-Methoden erfolgt sind (z.B. sichern der Zahl (Datum) aus dem Object über die SaveToFile- oder SaveToStream-Methoden, LoadFromFile, usw.), möchte ich für dieses Projekt keine so großen Änderungen mehr vornehmen.

Was mir jetzt nur noch fehlt ist die Sortierung meiner "Master"-TStringList nach der zweiten Datums-TStringList.
In beiden Listen sind in den Objecten die gleichen eindeutigen Zahlen gespeichert. Das heißt, beim befüllen der beiden TStringListen werden die jeweiligen Objecte mit den gleichen eindeutigen Nummern versehen.
Z. B. enthalten beide Listen im 4. Item die Object-Nr 8815468541, im 5. Item die Object-Nr 8815468542 usw.

Nun sortiere ich die zweite TStringList nach Datum, welches in den Items hinterrlegt ist.
Wie bekomme ich nun die Master-StringList so sortiert, dass diese dieselbe Reihenfolge hat wie die zweite TSringList? (Reihenfolge = die in dem Object hinterlegte Nummer)
Ich hoffe ich konnte mich verständlich ausdrücken was die Sortieranforderung betrifft.

Edit: Titel geändert.
Jürgen
Indes sie forschten, röntgten, filmten, funkten, entstand von selbst die köstlichste Erfindung: der Umweg als die kürzeste Verbindung zwischen zwei Punkten. (Erich Kästner)
  Mit Zitat antworten Zitat
idefix2

Registriert seit: 17. Mär 2010
Ort: Wien
1.027 Beiträge
 
RAD-Studio 2009 Pro
 
#5

AW: Sortierfunktion nach Datum in einer TStringList

  Alt 3. Jul 2015, 20:31
Egal wie du es machst, es wird extrem ineffizient werden, weil du in einer Stringlist nach einem bestimmten Wert in Objects nur sequentiell suchen kannst.
Wenn du nur zum Sortieren in eine extra Stringlist in Items das Datum schreibst und in Objects alle zu diesem Datum gehörenden Daten, dann kannst du, wenn im restlichen Programm eine Änderung der Datenstruktur zu kompliziert ist, nach dem Sortieren die Daten wieder in deine zwei Stringlisten aufteilen, bzw. ausgehend von deiner nach Datum sortierten Stringlist die zweite Stringliste neu erstellen.

Geändert von idefix2 ( 3. Jul 2015 um 20:35 Uhr)
  Mit Zitat antworten Zitat
Benutzerbild von DeddyH
DeddyH

Registriert seit: 17. Sep 2006
Ort: Barchfeld
27.537 Beiträge
 
Delphi 11 Alexandria
 
#6

AW: Sortierfunktion nach Datum in einer TStringList

  Alt 3. Jul 2015, 21:17
Ich (und vermutlich auch ein paar andere User) habe ein Problem damit, zusammengehörige Daten in unterschiedlichen Listen zu hinterlegen, das ist extrem fehleranfällig, vor allem dann, wenn aus welchen Gründen auch immer die Listen unterschiedlich viele Einträge enthalten, da sind AVs einfach vorprogrammiert. Von daher würde ich eher zur TObjectList tendieren, die kannst Du nach eigenem Gusto (um)sortieren, und eine Methode zur Ausgabe ist ja auch schnell geschrieben. Das mag zwar im Moment etwas Aufwand sein, aber erstens ist der überschaubar und zweitens zahlt sich das langfristig aus.
Detlef
"Ich habe Angst vor dem Tag, an dem die Technologie unsere menschlichen Interaktionen übertrumpft. Die Welt wird eine Generation von Idioten bekommen." (Albert Einstein)
Dieser Tag ist längst gekommen
  Mit Zitat antworten Zitat
Benutzerbild von juergen
juergen

Registriert seit: 10. Jan 2005
Ort: Bönen
1.164 Beiträge
 
Delphi 11 Alexandria
 
#7

AW: Sortierfunktion nach Datum in einer TStringList

  Alt 3. Jul 2015, 21:20
Danke an alle beteiligten!

Wie ich jetzt gemerkt habe, kann ich machen was ich will, ich habe immer irgendein Problem, solange ich nicht die Struktur ändere.
Ich schreibe nun wie ursprünglich erst einmal das Datum als Integer wieder in das jeweilige Object des Item. Die andere Erweiterung muss warten.
Dieser Thread ist somit gelöst!
Jürgen
Indes sie forschten, röntgten, filmten, funkten, entstand von selbst die köstlichste Erfindung: der Umweg als die kürzeste Verbindung zwischen zwei Punkten. (Erich Kästner)
  Mit Zitat antworten Zitat
Benutzerbild von Sir Rufo
Sir Rufo

Registriert seit: 5. Jan 2005
Ort: Stadthagen
9.454 Beiträge
 
Delphi 10 Seattle Enterprise
 
#8

AW: Sortierfunktion nach Datum in einer TStringList

  Alt 4. Jul 2015, 00:42
Das ist eigentlich alles was du brauchst:
Delphi-Quellcode:
unit MyObjectList;

interface

uses
  {System.}Classes,
  {System.}Generics.Collections,
  {System.}SysUtils;

type
  TMyObjectList<T: class> = class( TObjectList<T> )
  public
    procedure ToStrings( AStrings: TStrings; IncludeObjects: Boolean = false ); overload;
    procedure ToStrings( AStrings: TStrings; AConverter: TFunc<T, string>; IncludeObjects: Boolean = false ); overload;
  end;

implementation

{ TMyObjectList<T> }

procedure TMyObjectList<T>.ToStrings( AStrings: TStrings; IncludeObjects: Boolean );
begin
  ToStrings( AStrings,
    function( AItem: T ): string
    begin
      Result := AItem.ToString( );
    end, IncludeObjects );
end;

procedure TMyObjectList<T>.ToStrings( AStrings: TStrings; AConverter: TFunc<T, string>; IncludeObjects: Boolean );
var
  LItem: T;
begin
  AStrings.BeginUpdate;
  try
    AStrings.Clear;
    for LItem in Self do
    begin
      if IncludeObjects then
        AStrings.AddObject( AConverter( LItem ), LItem )
      else
        AStrings.Add( AConverter( LItem ) );
    end;
  finally
    AStrings.EndUpdate;
  end;
end;

end.
Da sammelst du alle Instanzen, sortierst diese, wie gewünscht und lässt dir mit den beiden Methoden die StringListen befüllen:
Delphi-Quellcode:
FFileInfos : TMyObjectList<TFileInfo>;

FFileInfos.Sort( {Sortier-Methode} ); // Sortierung für ListBox
FFileInfos.ToStrings(
  ListBox1.Items,
  True );

FFileInfos.Sort( {Sortier-Methode} ); // Sortierung für ComboBox
FFileInfos.ToStrings(
  ComboBox1.Items,
  function ( Item: TFileInfo ) : string
  begin
    Result := Format('%s (%d)',[Item.Name,Item.Size]);
  end,
  True );
Kaum macht man's richtig - schon funktioniert's
Zertifikat: Sir Rufo (Fingerprint: ‎ea 0a 4c 14 0d b6 3a a4 c1 c5 b9 dc 90 9d f0 e9 de 13 da 60)
  Mit Zitat antworten Zitat
Hansa

Registriert seit: 9. Jun 2002
Ort: Saarland
7.554 Beiträge
 
Delphi 8 Professional
 
#9

AW: Sortierfunktion nach Datum in einer TStringList

  Alt 4. Jul 2015, 12:40
Wie DeddyH würde ich auch raten, keine 2 Stringlisten zu benutzen. Die irgendwie zu synchronisieren ist echt zu fehlerträchtig, weil dann zwie Datenquellen vorhanden sind. Vor allem ist das aber auch unnötig. Deddy hat sa vielleicht zu knapp beschrieben.

Ich denke er meint (ungefähr zumindest) das, was ich jetzt etwas ausführlicher schreibe. Der Vorteil einer TObjectList ist ja der, dass man in die einzelnen Objekte dieser Liste so ziemlich alle Datentypen die es gibt, reinpacken kann. Definiere dir also einen Typ, der zumindest alles enthält, was angezeigt werden soll. Da geht natürlich auch noch mehr. Diese TObjectList füllst du dann mit deinen Daten.

Jetzt kommt das Stringgrid. Dieses wird gefüllt aus der TObjectList. Soll dieses jetzt sortiert werden, dann sortierst du die TObjectList, machst das Stringgrid leer und befüllst es wieder aus der sortierten TObjectList. Das wars dann. Wegen der TObjectList : das ist zwar Allzweckwaffe, aber man muss diese auch richtig benutzen. Beim Delphi-Treff gibts ein gutes Tutorial dazu.
Gruß
Hansa
  Mit Zitat antworten Zitat
Popov
(Gast)

n/a Beiträge
 
#10

AW: Sortierfunktion nach Datum in einer TStringList

  Alt 4. Jul 2015, 13:35
@juergen

Also die Idee von DeddyH ist wohl die Beste. Wenn Objekt bereits belegt ist, dann eine Klasse schreiben die sowohl dieses Objekt enthält wie auch ein Zweites. Letztendlich die einfachste Methode.

Trotzdem, hier mal eine "Trick 17" Methode. Liste (TStringList) enthält 1000 Daten mit Uhrzeiten. Dennoch wird sie korrekt alphabetisch sortiert. Der eigentliche Trick ist, dass die Daten anders gespeichert sind als sie angezeigt werden:

Delphi-Quellcode:
function DateTimeFormatDE: TFormatSettings;
begin
  Result.DateSeparator := '.';
  Result.TimeSeparator := ':';
  Result.ShortDateFormat := 'dd/MM/yyyy hh:nn:ss';
end;

function DateTimeFormatINT: TFormatSettings;
begin
  Result.DateSeparator := '-';
  Result.TimeSeparator := ':';
  Result.ShortDateFormat := 'yyyy/MM/dd hh:nn:ss';
end;

procedure ListeMitZufaelligenDatenGenerieren(List: TStrings; Max: Integer);
var
  i: Integer;
  dt: TDateTime;
begin
  for i := 1 to Max do
  begin
    dt := EncodeDateTime(Random(115) + 1900, Random(12) + 1, Random(28) + 1,
      Random(24), Random(60), Random(60), Random(1000));
    List.Add(DateTimeToStr(dt, DateTimeFormatDE)); //erstelle deutsch-typsch
  end;
end;

procedure DatenInListeInAnderesFormatAendern(List: TStrings);
var
  i: Integer;
  dt: TDateTime;
begin
  for i := 0 to List.Count - 1 do
  begin
    dt := StrToDateTime(List[i], DateTimeFormatDE); //lese deutsch-typsch
    List[i] := DateTimeToStr(dt, DateTimeFormatINT); //verändere international
  end;
end;

procedure TForm1.FormCreate(Sender: TObject);
begin
  //Datum deutsch-typisch 27.03.2015 14:58:36. Für Sortierung ungeeigent
  ListeMitZufaelligenDatenGenerieren(ListBox1.Items, 1000);

  //Datum untypisch 2015-03-27 14:58:36. Für Sortierung geeignet
  DatenInListeInAnderesFormatAendern(ListBox1.Items);

  ListBox1.Sorted := True;

  ListBox1.Style := lbOwnerDrawFixed;
end;

procedure TForm1.ListBox1DrawItem(Control: TWinControl; Index: Integer;
  Rect: TRect; State: TOwnerDrawState);
var
  Delta: Integer;
  dt: TDateTime;
  s: String;
begin
  with (Control as TListbox) do
  begin
    //Das Datum ist in der StringList untypisch gespeichert: 2015-03-27 14:58:36
    //Hier wird es für die typische Darstellung 27.03.2015 14:58:36 verändert.

    dt := StrToDateTime(Items[Index], DateTimeFormatINT); //lese international
    s := DateTimeToStr(dt, DateTimeFormatDE); //erstelle deutsch-typsch

    Delta := (ItemHeight div 2) - (Canvas.TextHeight(Items[Index]) div 2);
    Canvas.TextRect(Rect, Rect.Left + 2, Rect.Top + Delta, s);
  end;
end;
  Mit Zitat antworten Zitat
Antwort Antwort
Seite 1 von 2  1 2      


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 11:56 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