(Ich weiß, das ein Jahr später, aber immer noch nützliche Dinge.)
Skamradt Vorschlag aufzufüllen ganzzahlige Werte annimmt, die Sie sortieren wollen eine Zeichenfolge vergleichen mit. Das wäre langsam. Aufrufformat() für jede Einfügung, langsamer noch. Stattdessen möchten Sie einen Ganzzahlvergleich durchführen.
Sie beginnen mit einem Satztyp:
TExample = record
SortOrder : integer;
SomethingElse : string;
end;
Sie nicht angeben, wie die Datensätze gespeichert wurden, oder wie man sie wollte einmal zugreifen sortiert. Also lassen Sie uns annehmen, dass Sie sie in einem dynamischen Array setzen:
var MyDA Array of TExample;
...
SetLength(MyDA,NewSize); //allocate memory for the dynamic array
for i:=0 to NewSize-1 do begin //fill the array with records
MyDA[i].SortOrder := SomeInteger;
MyDA[i].SomethingElse := SomeString;
end;
Jetzt können Sie durch den ganzzahligen Wert SortOrder dieses Array sortieren möchten. Wenn Sie eine TStringList (also die ts.Find-Methode) verwenden möchten, sollten Sie jede Zeichenfolge zur Liste hinzufügen und SortOrder als Zeiger hinzufügen. Dann sortieren auf den Zeiger:
var tsExamples: TStringList; //declare it somewhere (global or local)
...
tsExamples := tStringList.create; //allocate it somewhere (and free it later!)
...
tsExamples.Clear; //now let's use it
tsExamples.sorted := False; //don't want to sort after every add
tsExamples.Capacity := High(MyDA)+1 //don't want to increase size with every add
//an empty dynamic array has High() = -1
for i:=0 to High(MyDA) do begin
tsExamples.AddObject(MyDA[i].SomethingElse,TObject(MyDA[i].SortOrder));
end;
Hinweis den Trick der Integer SortOrder in einen TObject Zeiger Gießen, die in der TStringList.Object Eigenschaft gespeichert wird. (Dies hängt von der Tatsache, dass Integer und Zeiger die gleiche Größe haben.) Irgendwo wir eine Funktion definieren, müssen die TObject Zeiger vergleichen:
function CompareObjects(ts:tStringList; Item1,Item2: integer): Integer;
var i,j: integer;
begin
Result := integer(ts.Objects[i]) - integer(ts.Objects[j];
end;
Jetzt können wir die tsList auf .Object sortieren, indem .CustomSort Aufruf statt von .Sort (die auf der String-Wert sortieren würde.)
tsExample.CustomSort(@CompareObjects); //Sort the list
The TStringList jetzt sortiert, so dass Sie über sie von 0 bis .Count-1 und lesen Sie die Saiten in sortierter Reihenfolge durchlaufen können.
Angenommen, Sie wollten keine TStringList, nur ein Array in sortierter Reihenfolge. Oder die Datensätze enthalten mehr Daten als nur die eine Zeichenfolge in diesem Beispiel, und Ihre Sortierreihenfolge ist komplexer. Sie können den Schritt des Hinzufügens jeder Zeichenfolge überspringen und den Array-Index einfach als Elemente in einer TList hinzufügen. Tun Sie alles über die gleiche Art und Weise, mit der Ausnahme eines TList anstelle von TStringList:
var Mlist: TList; //a list of Pointers
...
for i:=0 to High(MyDA) do
Mlist.add(Pointer(i)); //cast the array index as a Pointer
Mlist.Sort(@CompareRecords); //using the compare function below
function CompareRecords(Item1, Item2: Integer): Integer;
var i,j: integer;
begin
i := integer(item1); //recover the index into MyDA
j := integer(item2); // and use it to access any field
Result := SomeFunctionOf(MyDA[i].SomeField) - SomeFunctionOf(MyDA[j].SomeField);
end;
Nun, da Mlist sortiert ist, verwenden Sie es als eine Nachschlagtabelle das Array in sortierter Reihenfolge zuzugreifen:
for i:=0 to Mlist.Count-1 do begin
Something := MyDA[integer(Mlist[i])].SomeField;
end;
Wie Wenn ich über die TList iteriert, erhalten wir die Array-Indizes in sortierter Reihenfolge zurück. Wir müssen sie nur auf Integers zurückwerfen, da die TList denkt, dass sie Zeiger sind.
Ich mag es so, aber Sie könnten auch echte Zeiger auf Array-Elemente in der TList setzen, indem Sie die Adresse des Array-Elements anstelle von dessen Index hinzufügen. Um sie dann zu verwenden, würden Sie sie als Zeiger auf TExample-Datensätze ausgeben. Das sagen Barry Kelly und CoolMagic in ihren Antworten.
Gerade durch diese Übung ging und fand den besten Weg, um meine eigenen Code zu schreiben ist. Ich denke nicht, dass eine der Antworten als ** best ** empfohlen werden sollte. – Sam
Punkt genommen. Vielleicht könnten Sie auch eine Antwort mit Ihrer Lösung für das Problem hinzufügen? – Marius
Es gibt einige gute Informationen in Tomes von Delphi Algorithmen und Datenstrukturen von Julian Bucknall. (s –