Wie Sortiere ich eine generische Liste mit einer benutzerdefinierten comparer?
Ich bin irgendwie ein Delphi-Neuling und ich weiß nicht, wie die Sort-Methode, eine TList von Datensätzen aufgerufen wird, um zu Sortieren die Datensätze nach aufsteigenden integer-Wert.
Ich habe einen Datensatz wie folgt:
type
TMyRecord = record
str1: string;
str2: string;
intVal: integer;
end;
Sowie eine generische Liste von solchen Aufzeichnungen:
TListMyRecord = TList<TMyRecord>;
Habe versucht zu finden ein code-Beispiel in die Hilfe-Dateien und fand dieses:
MyList.Sort(@CompareNames);
Welche ich nicht verwenden kann, da es verwendet Klassen. Also versuchte ich zu schreiben, meine eigene compare-Funktion mit etwas anderen Parametern:
function CompareIntVal(i1, i2: TMyRecord): Integer;
begin
Result := i1.intVal - i2.intVal;
end;
Aber der compiler wirft immer ein "nicht genügend Parameter" - Fehler, wenn ich rufen Sie es mit open.Sort(CompareIntVal);
, was offensichtlich scheint; so habe ich versucht, näher an die Hilfe Datei:
function SortKB(Item1, Item2: Pointer): Integer;
begin
Result:=PMyRecord(Item1)^.intVal - PMyRecord(Item2)^.intVal;
end;
mit PMyRecord als PMyRecord = ^TMyRecord;
Habe ich versucht, verschiedene Möglichkeiten, eine Funktion aufrufen, die immer wieder einige Fehler...
InformationsquelleAutor p1.e | 2012-11-06
Du musst angemeldet sein, um einen Kommentar abzugeben.
Den
Sort
überlastung, die Sie verwenden sollten, ist diese:Nun, Sie können erstellen einen
IComparer<TMyRecord>
durch den AufrufTComparer<TMyRecord>.Construct
. Wie diese:Habe ich geschrieben das
Comparison
Funktion als anonyme Methode, aber Sie können auch eine einfache alte Stil nicht-OOP-Funktion oder eine Methode ein Objekt.Einem problem mit der Vergleich-Funktion ist, dass Sie leiden können integer-überlauf. So könnte man statt dessen den Standard-integer-comparer.
Könnte es teuer werden, rufen Sie
TComparer<Integer>.Default
wiederholt, so konnte Sie speichern Sie es Weg in eine Globale variable:Andere option zu prüfen, ist zu passieren in der comparer beim erstellen der Liste. Wenn Sie immer nur die Liste zu Sortieren verwenden Sie diese Reihenfolge, dann ist das bequemer.
Dann Sortieren Sie die Liste mit
uses Generics.Collections,...
, 'Ursache, die ich eine "schwarzarbeit" fürTComparison
undIComparer
imvar Comparison: TComparison<TKanteRecord>; IntegerComparer: IComparer<Integer>;
?Sie müssen auch die Generika.Standardwerte. Haben Sie festgestellt, dass die RTL-source-code noch. Das würde Ihnen helfen.
sind Sie sicher, dass
TComparer
ist eine gute Wahl für einen code, den Sie zur Verfügung gestellt ?TComparer
gemeint ist die abstrakte Basisklasse. Ich würde vorschlagen, zu verwendenTDelegatedComparer
für Ihren code.Ja, ich bin sicher, dass:
TComparer<T>.Construct(Comparison)
ist umgesetzt mit einem AufrufTDelegatedComparer<T>.Create(Comparison)
.Die TList<T> nicht über einen Konstruktor verfügen, akzeptieren TComparer<T> als input-parameter in Delphi 10.2. Könnten Sie kompilierbare Beispiele?
InformationsquelleAutor David Heffernan
Die knappe Antwort:
InformationsquelleAutor Ian Boyd
Fand ich eine viel einfachere modifizierte Funktion Sortieren auf alphabetisch, eine TList von Datensätzen oder nicht standardisierte Liste von Elementen.
Beispiel
und die Funktion, um den Anruf zu Sortieren Sie Ihre Liste
Die ursprüngliche Frage war zum Sortieren eine generische Liste, die während dieses Beispiel nutzt die standard-TList (Liste der Verweise), die ein anderes Szenario.
InformationsquelleAutor Jason Brown
Möchte ich meine Lösung (basierend auf dem input, den ich hier versammelt haben).
Es ist ein standard-setup. Ein filedata Klasse, der hält, was Daten aus einer Datei in eine generische TObjectList. Die Liste hat zwei private Attribute fCurrentSortedColumn und fCurrentSortAscending zu Steuerung der Sortierreihenfolge. Der AsString-Methode gibt den Pfad und den Dateinamen kombiniert.
InformationsquelleAutor Henrik Carlsen