Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Object-Pascal / Delphi-Language (https://www.delphipraxis.net/32-object-pascal-delphi-language/)
-   -   Delphi TStringList absteigend sortieren (https://www.delphipraxis.net/170194-tstringlist-absteigend-sortieren.html)

XxnemesisxX49 4. Sep 2012 21:59

Delphi-Version: 7

TStringList absteigend sortieren
 
Guten Abend zusammen,

ich habe nun schon sämtliche Foren durchkämmt, doch finde keine Lösung für mein Problem.
Ich möchte Werte in einer TStringlist absteigend sortieren. Bisher habe ich es mit dem Code unten versucht, jedoch werden die Werte wie folgt sortiert:
22
20000
200
20
Code:
function StringListSortCompare(List: TStringList; Index1, Index2: integer): integer;
begin
  if List.CaseSensitive
    then Result := AnsiCompareStr(List[Index2], List[Index1])
    else Result := AnsiCompareText(List[Index2], List[Index1]);
end;
Ich hätte sie aber gerne so sortiert:
20000
200
22
20

Ich hoffe ihr könnt mir weiterhelfen und schon mal vielen Dank im Voraus :-D

Luckie 4. Sep 2012 22:12

AW: TStringList abwertend sortieren
 
Du vergleichst ja auch Zeichen und keine Ganzzahlen.

XxnemesisxX49 4. Sep 2012 22:14

AW: TStringList abwertend sortieren
 
Gibt es eine Möglichkeit ganze Zahlen zu vergleichen?

Luckie 4. Sep 2012 22:26

AW: TStringList abwertend sortieren
 
Klar. Mit <, > und =.

XxnemesisxX49 4. Sep 2012 22:35

AW: TStringList abwertend sortieren
 
Kann ich den Code, den ich gepostet hab, irgendwie so umändern, dass er tut was ich will :-D

himitsu 4. Sep 2012 22:39

AW: TStringList abwertend sortieren
 
Zitat:

Gibt es eine Möglichkeit ganze Zahlen zu vergleichen?
Ja, kann man.

z.B., wenn man vor dem Vergleich die Strings in Zahlen umwandelt. :roll:

Bjoerk 4. Sep 2012 22:39

AW: TStringList abwertend sortieren
 
Schau die an, welche Ergebnisse AnsiCompareStr liefert und schreib' die Function so um, daß du diese Ergebnisse hast, indem du StrToInt(List[Index1]) mit StrToInt(List[Index2]) vergleichst. Es gibt drei Fälle.

Delphi-Quellcode:
function Compare(List: TStringList; Index1, Index2: Integer): Integer;
begin
  Result:= ?;
  if StrToInt(List[Index1]) > StrToInt(List[Index2]) then
    Result:= ?
  else
    if StrToInt(List[Index1]) < StrToInt(List[Index2]) then
      Result:= ?;
end;

Jumpy 4. Sep 2012 22:40

AW: TStringList abwertend sortieren
 
Man könnte die Strings in der Lise in Zahlen umwandeln und vergleichen oder in(nerhalb) der Vergleichsfunktion links mit nullen auffüllen. Weiß nicht, ob's da einen Befehl für gibt, bei OracleSQL wär das LPAD.

himitsu 4. Sep 2012 22:53

AW: TStringList abwertend sortieren
 
Zitat:

Zitat von Bjoerk (Beitrag 1181589)
Schau die an, welche Ergebnisse AnsiCompareStr liefert und

Wobei in der OH auch drinsteht, welche Werte das Result dieses Delphi-Referenz durchsuchenTStringListSortCompare haben soll.

PS: Teilweise kennt Delphi auch noch andere Funktionen, welche soein Ergebnis liefern.
Delphi-Referenz durchsuchenCompareValue

XxnemesisxX49 4. Sep 2012 23:15

AW: TStringList abwertend sortieren
 
Juhu, es funktioniert, danke :-D

Ich hab noch eine Frage.
Wenn ich jetzt Zahlen mit Namen sortieren will, funktioniert die Methode nicht mehr, weil die Namen ja keine Integers sein können.
Bsp.:
2000 Peter
500 Hans
20 Alex

Gibt's da auch eine Lösung, die nicht all zu schwer ist? :-D

himitsu 4. Sep 2012 23:46

AW: TStringList abwertend sortieren
 
Dieses nennt sich z.B. "Natural Sort" oder Dergleichen.

Es gibt schon irgendwo fertige Funktionen für diesen Vergleich, aber im Prinzip läuft es auf das selbe Grundprinzip hinaus.
Die Strings werden in Buchstaben- und Nummernblöcke aufgeteilt und dann werden von vorne nach hinten die Blöcke "getrennt" verglichen.
Also ein Teil wird verglichen, bei Gleichheit wird der nächste Block verglichen und bei Ungleichheit wird dieses Ergebnis oder das letzte Ergebnis zurückgegeben.

Medium 4. Sep 2012 23:48

AW: TStringList abwertend sortieren
 
Definiere "all zu schwer"

Furtbichler 5. Sep 2012 06:49

AW: TStringList abwertend sortieren
 
Zitat:

Zitat von XxnemesisxX49 (Beitrag 1181593)
Gibt's da auch eine Lösung, die nicht all zu schwer ist? :-D

Ja. Hast Du es schon selbst versucht? Wie würdest Du an die Sache herangehen?

Schau Dir mal die Befehle Delphi-Referenz durchsuchenPos und Delphi-Referenz durchsuchenCopy an.

Bummi 5. Sep 2012 07:09

AW: TStringList abwertend sortieren
 
Je nach Datenherkunft bist Du am schnellsten wenn Du den numerischen Teil mit führenden "0" auf gleiche Längen bringst und dann wieder einen Stringcompare verwendest.

ibp 5. Sep 2012 09:16

AW: TStringList abwertend sortieren
 
ist zwar nicht meine Art trotzdem sticht mir immer wieder das "abwertend" im Titel ins Auge. Könntest du das bitte in "absteigend" ändern?

user0815 5. Sep 2012 10:55

AW: TStringList abwertend sortieren
 
Gibt's da auch eine Lösung, die nicht all zu schwer ist?


Delphi-Quellcode:
unit Unit1;

interface

uses
  Windows, SysUtils, Classes, Forms, StdCtrls, Controls;

type
  TZusatzDaten = class(TObject)
   public
     FVorname : string;
     FAlter : Integer;
     constructor Create(Vorname: string; Alter : Integer);
  end;

type
  TForm1 = class(TForm)
    Button1: TButton;
    Memo1: TMemo;
    procedure Button1Click(Sender: TObject);

  private
    { Private-Deklarationen }
    sl : TStringList;

  public
    { Public-Deklarationen }
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

constructor TZusatzDaten.Create(Vorname : string; Alter : Integer);
begin
  Self.FVorname := Vorname;
  Self.FAlter := Alter;
end;

procedure TForm1.Button1Click(Sender: TObject);
var
  i,j : Integer;
  Eintrag : TZusatzDaten;
begin
  Memo1.Clear;
  sl := TStringList.Create;

  try
    sl.AddObject('Franzen', TZusatzdaten.Create('Dieter', 36));
    sl.AddObject('Hansen', TZusatzdaten.Create('Hans', 45));
    sl.AddObject('Petersen', TZusatzdaten.Create('Klara', 21));

    // Wert an Position "Hansen" einfügen
    i := sl.IndexOf('Hansen');
    sl.InsertObject(i, 'Paulsen', TZusatzDaten.Create('Paul', 29));

    // Wert ändern
    Eintrag := TZusatzDaten(sl.Objects[0]);
    Eintrag.FVorname := 'Franz';

    // Wert anders ändern
    Eintrag := sl.Objects[3] as TZusatzDaten;
    Eintrag.FVorname := 'Peter';

    for i := 0 to sl.Count -1 do
      Memo1.Lines.Append(sl[i] + ', ' + TZusatzdaten(sl.Objects[i]).FVorname + ' Alter: ' + IntToStr(TZusatzdaten(sl.Objects[i]).FAlter));

    Memo1.Lines.Append('');
    Memo1.Lines.Append('sl Sortieren');
    sl.Sort; // Sortieren

    for i := 0 to sl.Count -1 do
      Memo1.Lines.Append(sl[i] + ', ' + TZusatzdaten(sl.Objects[i]).FVorname + ' Alter: ' + IntToStr(TZusatzdaten(sl.Objects[i]).FAlter));

    sl.Exchange(0,1); // die beiden Werte tauschen

    Memo1.Lines.Append('');
    Memo1.Lines.Append('Tauschen 0 & 1');

    for i := 0 to sl.Count -1 do
      Memo1.Lines.Append(sl[i] + ', ' + TZusatzdaten(sl.Objects[i]).FVorname + ' Alter: ' + IntToStr(TZusatzdaten(sl.Objects[i]).FAlter));

    // Nach Alter sortieren
    for i := sl.Count -1 downto 1 do
     for j := 1 to i do
      if TZusatzdaten(sl.Objects[j-1]).FAlter > TZusatzdaten(sl.Objects[j]).FAlter
       then sl.Exchange(j-1,j);

    Memo1.Lines.Append('');
    Memo1.Lines.Append('Nach Alter sortieren');

    for i := 0 to sl.Count -1 do
      Memo1.Lines.Append(sl[i] + ', ' + TZusatzdaten(sl.Objects[i]).FVorname + ' Alter: ' + IntToStr(TZusatzdaten(sl.Objects[i]).FAlter));

  finally
     for i := 0 to sl.Count -1 do
      if Assigned(sl.Objects[i])
       then sl.Objects[i].Free;

    sl.Free;
  end;
end;

end.

BUG 5. Sep 2012 11:30

AW: TStringList abwertend sortieren
 
Lösungen findest du eventuell auch in dem Thread mit dem lustigen Namen: Intelligentes BubleSort; sortieren wie im Windows Explorer

SirThornberry 5. Sep 2012 12:33

AW: TStringList abwertend sortieren
 
Das einfachste wäre nicht Zahl+Text in der Stringliste zu hinterlegen sondern eine Liste zu nehmen die zum Beispiel Records oder Objekte enthält so das du den Zahlen und Textteil direkt ansprechen kannst und nicht erst jedesmal den String in seine Bestandteile zerlegen.

XxnemesisxX49 5. Sep 2012 14:52

AW: TStringList abwertend sortieren
 
Zitat:

Zitat von Furtbichler (Beitrag 1181616)
Ja. Hast Du es schon selbst versucht? Wie würdest Du an die Sache herangehen?

Schau Dir mal die Befehle Delphi-Referenz durchsuchenPos und Delphi-Referenz durchsuchenCopy an.

Ja, langsam fängt mein Kopf auch schon an zu qualmen. Ich schätze mal, ich muss den String in 2 Teile teilen, die Zahlenteile sortieren und den Textteil dann wieder entsprechend hinzufügen?
Ich hoffe, das war nicht allzu falsch, aber ich arbeite mit Delphi nur einmal pro Woche in der Schule und das auch noch nicht so lange. Vor 2 Monaten wusste ich noch nicht einmal was eine TStringlist ist. Dementsprechend sind halt auch meine Kenntnisse :?

Zitat:

Zitat von ibp (Beitrag 1181631)
ist zwar nicht meine Art trotzdem sticht mir immer wieder das "abwertend" im Titel ins Auge. Könntest du das bitte in "absteigend" ändern?

Wenn du mir sagst, wie ich das mache.

Zitat:

Zitat von SirThornberry (Beitrag 1181659)
Das einfachste wäre nicht Zahl+Text in der Stringliste zu hinterlegen sondern eine Liste zu nehmen die zum Beispiel Records oder Objekte enthält so das du den Zahlen und Textteil direkt ansprechen kannst und nicht erst jedesmal den String in seine Bestandteile zerlegen.

Ich habe aber bisher nur TStringlists gelernt :?

mkinzler 5. Sep 2012 15:03

AW: TStringList abwertend sortieren
 
Zitat:

Zitat von ibp:
ist zwar nicht meine Art trotzdem sticht mir immer wieder das "abwertend" im Titel ins Auge. Könntest du das bitte in "absteigend" ändern?
Wenn du mir sagst, wie ich das mache.
Deinen 1. Beitrag im erweiterten Modus bearbeiten

shmia 5. Sep 2012 15:42

AW: TStringList absteigend sortieren
 
Liste der Anhänge anzeigen (Anzahl: 1)
Also die Grundlage für Natural Sort ist Natural Compare.
Das ist gar nicht so einfach, aber ich hab mir da mal etwas Code von der DP geklaut (Danke xaromz!) und nochmals verbessert.
Herausgekommen ist eine Unit, die man so direkt verwenden kann.
Man müsste vielleicht noch Anpassungen für die höheren Delphi Versionen mit Unicode vornehmen und könnte die Unit dann in die Code-Library eintüten.

Delphi-Quellcode:
// Anwendungsbeispiel zum "natürlichen" Sortieren
function StringListSortCompare(List: TStrings; Index1, Index2: integer): integer;
begin
  // Index1 und Index2 sind vertauscht -> absteigend sortieren
  if List.CaseSensitive
    then Result := NaturalCompareStr(List[Index2], List[Index1])
    else Result := NaturalCompareText(List[Index2], List[Index1]);
end;

XxnemesisxX49 5. Sep 2012 16:02

AW: TStringList absteigend sortieren
 
Ich hab soweit alles eingefügt, aber bei
Code:
type
   TTextCompFunc = function(const S1, S2: string):Integer;
zeigt er mir den Fehler "':' erwartet, aber '=' gefunden" an. Wenn ich dann aber : hinschreibe, erscheint die Fehlermeldung "ein Bezeichner erwartet aber FUNCTION gefunden."

Was muss ich da noch verändern? :)

shmia 5. Sep 2012 16:13

AW: TStringList absteigend sortieren
 
Zitat:

Zitat von XxnemesisxX49 (Beitrag 1181702)
zeigt er mir den Fehler "':' erwartet, aber '=' gefunden" an.

Welche Delphi Version?
Die Typdeklaration ist eigentlich schon seit Delphi 1 legal und müsste so selbst in Turbo-Pascal möglich sein.
Sehr seltsam...
Vielleicht ist TTextCompFunc schon irgendwo in der VCL definiert und man müsste nur den Namen umbenennen (z.B. nach TTextCompareFunc).

XxnemesisxX49 5. Sep 2012 16:19

AW: TStringList absteigend sortieren
 
Delphi 7

XxnemesisxX49 5. Sep 2012 16:20

AW: TStringList absteigend sortieren
 
Delphi 7

DeddyH 5. Sep 2012 16:24

AW: TStringList absteigend sortieren
 
Hast Du den Quelltext irgendwo reinkopiert, oder die Unit heruntergeladen und unter dem richtigen Namen gespeichert?

XxnemesisxX49 5. Sep 2012 16:34

AW: TStringList absteigend sortieren
 
Zitat:

Zitat von shmia (Beitrag 1181705)
Vielleicht ist TTextCompFunc schon irgendwo in der VCL definiert und man müsste nur den Namen umbenennen (z.B. nach TTextCompareFunc).

Hab ich probiert, gleicher Fehler.

Zitat:

Zitat von DeddyH (Beitrag 1181710)
Hast Du den Quelltext irgendwo reinkopiert, oder die Unit heruntergeladen und unter dem richtigen Namen gespeichert?

Ich habe alles in mein Programm reinkopiert, aber an die richtigen Stellen, meiner Meinung nach...:-D

DeddyH 5. Sep 2012 16:56

AW: TStringList absteigend sortieren
 
Dann kopier das wieder raus :mrgreen:, speichere die Unit unter "NatCompare.pas" in Deinem Delphi-Suchpfad oder dem Projektverzeichnis ab und binde sie in die uses-Klausel ein.

XxnemesisxX49 5. Sep 2012 17:03

AW: TStringList absteigend sortieren
 
Zitat:

Zitat von DeddyH (Beitrag 1181713)
in Deinem Delphi-Suchpfad oder dem Projektverzeichnis ab und binde sie in die uses-Klausel ein.

also in dem Ordner, wo das Projekt und die Unit gepspeichert sind?

Wie binde ich sie denn in die uses-Klausel ein? Das hab ich noch nie gemacht.

DeddyH 5. Sep 2012 17:07

AW: TStringList absteigend sortieren
 
Na, einfach dahinter schreiben, mit Komma getrennt.
Delphi-Quellcode:
uses
  Windows, Messages, SysUtils, {usw.}, NatCompare;

XxnemesisxX49 5. Sep 2012 17:17

AW: TStringList absteigend sortieren
 
ok, hab ich.
Das kommt dann einfach in meine Unit oder?
Delphi-Quellcode:
// Anwendungsbeispiel zum "natürlichen" Sortieren
function StringListSortCompare(List: TStrings; Index1, Index2: integer): integer;
begin
  // Index1 und Index2 sind vertauscht -> absteigend sortieren
  if List.CaseSensitive
    then Result := NaturalCompareStr(List[Index2], List[Index1])
    else Result := NaturalCompareText(List[Index2], List[Index1]);
end;

shmia 5. Sep 2012 17:20

AW: TStringList absteigend sortieren
 
Probier's aus! 8-)

XxnemesisxX49 5. Sep 2012 17:29

AW: TStringList absteigend sortieren
 
Ich glaube, das ist eine der letzten Fragen :D

Sortiere ich dann mit liste.CustomSort(StringListSortCompare) oder etwas ähnlichem?
...bestimmt falsch..:wall:

BUG 5. Sep 2012 17:36

AW: TStringList absteigend sortieren
 
Zitat:

Zitat von XxnemesisxX49 (Beitrag 1181721)
Sortiere ich dann mit liste.Delphi-Referenz durchsuchenCustomSort(StringListSortCompare) oder etwas ähnlichem?
...bestimmt falsch..:wall:

Wieso so pessimistisch? Probiere es aus oder gucke in die Hilfe :wink:

XxnemesisxX49 5. Sep 2012 17:37

AW: TStringList absteigend sortieren
 
Juhu, es klappt, ich könnte tanzen :D

Danke euch allen, für euer Durchhaltevermögen und, dass ihr so nem Deppen wie mir, der für jede Kleinigkeit Hilfe braucht, geholfen habt :mrgreen:

XxnemesisxX49 5. Sep 2012 17:40

AW: TStringList absteigend sortieren
 
Zitat:

Zitat von BUG (Beitrag 1181722)
Zitat:

Zitat von XxnemesisxX49 (Beitrag 1181721)
Sortiere ich dann mit liste.Delphi-Referenz durchsuchenCustomSort(StringListSortCompare) oder etwas ähnlichem?
...bestimmt falsch..:wall:

Wieso so pessimistisch? Probiere es aus oder gucke in die Hilfe :wink:

Da sollte eigentlich noch ein :mrgreen: hin.
Wie so ein fehlender Smiley die Bedeutung ändern kann, ist echt erstaunlich :D


Alle Zeitangaben in WEZ +1. Es ist jetzt 14:09 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