Registriert seit: 24. Dez 2017
15 Beiträge
Delphi XE2 Enterprise
|
AW: Delphi Listbox Items nach Teil String sortieren
24. Dez 2017, 13:16
So das Ganze noch einmal:
Code:
//=====================================================================================================================
// Die eigentliche Sortier-Callback Funktion
// Hier werden die eigentliche Liste, sowie zwei Indizes der Liste zur Verfügung gestellt.
// Man muss nun die beiden Elemente der Liste miteinander Vergleichen,
// die über die Indizes zur Verfügung stehen.
//
// Ist das Element der Liste mit dem Index1 größer als das Element der Liste mit dem Index2,
// so muss man als Rückgabe Parameter dieser Funktion eine 1 einsetzen.
//
// Ist das Element der Liste mit dem Index1 kleiner als das Element der Liste mit dem Index2,
// so muss man als Rückgabe Parameter dieser Funktion eine -1 einsetzen.
//
// Sind beide Elemente gleich,
// so muss man als Rückgabe Parameter dieser Funktion eine 0 einsetzen.
//
// Der eigentliche Sortieralgorithmus ist Quicksort, der vom Objekt TStringlist,
// auf die hier gezeigte Weise zur Verfügung steht.
// Man kann sogar in gewohnter Weise auf die Objektliste zugreifen.
// z.B. TIrgendetwas(List.Objects[index1])
//
// Ich habe hier beim Vergleichen die ausführliche Schreibweise der If Anweisungen gewählt.
// Bei einem Einfachen Vergleich ist das zwar nicht nötig, doch bei Erweiterungen bietet
// die Variante mit dem "Exit" in den jeweiligen Zweigen vielfältige Möglichkeiten um
// z.B. verschachtelt zu sortieren. (Wie man es z.b.von Excel kennt - Erst nach Spalte A dann nach Spalte C.... usw.)
//=====================================================================================================================
// Die Führenden Ziffern des Strings als Integer interpretieren und danach sortieren, wie es eigentlich snnvoll ist.
Function MySortByNumbersAsValue(list:TStringlist;Index1:Integer;Index2:Integer):Integer;
Var A,B:Integer;
begin
Result:=0;
a:=StrToInt(Copy(list[index1],1,Pos(#32,(list[index1]))-1));
b:=StrToInt(Copy(list[index2],1,Pos(#32,(list[index2]))-1));
if A>B then
begin
Result:=1;
Exit;
end;
if A<B then
begin
Result:=-1;
Exit;
end;
end;
// Einfach die Strings sortieren wie sie sind, wie es z.b. der Explorer mit Dateinamen macht.
Function MySortByFirstChars(list:TStringlist;Index1:Integer;Index2:Integer):Integer;
Var A,B:String;
begin
Result:=0;
a:=list[index1];
b:=list[index2];
if A>B then
begin
Result:=1;
Exit;
end;
if A<B then
begin
Result:=-1;
Exit;
end;
end;
//=====================================================================================================================
//Sortieren der Liste nach Nummern
//=====================================================================================================================
procedure TForm1.Button1Click(Sender: TObject);
Var l:Tstringlist;
begin
l:=TStringlist.Create;//Hilfsliste erzeugen
Listbox1.Items.BeginUpdate;//Listbox Zeichnen einfrieren
l.Assign(Listbox1.items);//Inhalt der Listbox in die Hilfsliste kopieren
l.CustomSort(MySortByNumbersAsValue);//Hilfsliste sortieren, wobei die führenden ziffern in Zahlen umgewandelt wurden.
Listbox1.Items.Assign(L);//Hilfsliste zurück in die Listbox kopieren
l.free;//Hilfsliste wieder freigeben
Listbox1.Items.EndUpdate;//Listbox Zeichnen wieder freigeben
end;
//=====================================================================================================================
//Füllen der Listbox mit Zufallswerten für den Test
//=====================================================================================================================
procedure TForm1.Button2Click(Sender: TObject);
Var l:Tstringlist;
begin
l:=TStringlist.Create;//Hilfsliste erzeugen
Listbox1.Items.BeginUpdate;//Listbox Zeichnen einfrieren
l.Assign(Listbox1.items);//Inhalt der Listbox in die Hilfsliste kopieren
l.CustomSort(MySortByFirstChars);//Hilfsliste einfach nach Zeichen sortieren wie in einem Telefonbuch
Listbox1.Items.Assign(L);//Hilfsliste zurück in die Listbox kopieren
l.free;//Hilfsliste wieder freigeben
Listbox1.Items.EndUpdate;//Listbox Zeichnen wieder freigeben
end;
procedure TForm1.FormCreate(Sender: TObject);
Var i,j:Byte;
h:string;
begin
Listbox1.Items.BeginUpdate;//Listbox Zeichnen einfrieren
for i:= 1 to 100 do
begin
h:=Inttostr(Random(1000))+' ';
for j:=1 to Random(10)+5 do
begin
h:=h+Char(Random(25)+65);
end;
h:=h+' ';
h:=h+Inttostr(Random(1000))+' ';
for j:=1 to Random(10)+5 do
begin
h:=h+Char(Random(25)+65);
end;
Listbox1.Items.add(h);
end;
Listbox1.Items.EndUpdate;//Listbox Zeichnen wieder freigeben
end;
|
|
Zitat
|