![]() |
Ich habe eine Liste, und die soll bitte immer sortiert sein
(Anmerkung: Es könnte auch in
![]() Ich habe einen Datentyp, der bislang ein reiner Alias war:
Delphi-Quellcode:
Ich möchte nun sicherstellen, dass die Liste immer nach einem bestimmten Kriterium sortiert wird (beispielsweise aufsteigend des ersten Single-Wertes). Wo muss ich in meiner zu bildenden Unterklasse ansetzen? Ich kenne das
TMeinDatentyp = TList<TPair<Single, Single>>
Delphi-Quellcode:
-Event, aber das würde mir beim Einfügen von mehreren Einträgen gleich mehrmals feuern. Weiterhin wüsste ich nie, wann denn nun bei einem
OnNotify
Delphi-Quellcode:
das letzte Notify-Event gefeuert wurde und ich nun sortieren muss. Ein
AddRange
Delphi-Quellcode:
scheint es für Listen ja auch nicht zu geben.
Begin/EndUpdate
Delphi für .NET schien zweitweise ja mal die ![]() |
AW: Ich habe eine Liste, und die soll bitte immer sortiert sein
Sortierte Listen brauchen kein Begin/EndUpdate, da sie das Add's direkt an der "richtigen" Stelle via Insert einfügen.
Aber das kann keine der generischen Listen. Du kannst da nur immer am Ende TList<T>.Sort aufrufen. Automatisch sortieren kann die nicht. Ich kenn sowas nur von der TStringList. Es gibt nur einige der anderen Listen, die immer sortiert sind, z.B. die Dictionaries, aber da sind die nur nach ihren Hash's sortiert. Zitat:
AddRange geht auf InsertRange.
Delphi-Quellcode:
Alles hinzufügen und danach dann für Alle die Notify.
procedure TList<T>.InsertRange(Index: Integer; const Values: array of T);
begin ... for i := 0 to Length(Values) - 1 do Notify(Values[i], cnAdded); end; Da gibt es keinen "Letzten" zum erkennen. |
AW: Ich habe eine Liste, und die soll bitte immer sortiert sein
Genau. Das Dictionary hätte mir im Endeffekt nur das Gefummel mit TPair<X,Y> erspart, aber ich möchte ja jetzt explizit die Reihenfolge kontrollieren.
Ich könnte notfalls den Enumerator-Getter überschreiben so dass die Liste vorher sortiert wird. Aber indizierten Zugriff auf die Liste hätte ich damit auch nicht abgedeckt... |
AW: Ich habe eine Liste, und die soll bitte immer sortiert sein
Du könntest von der Liste ableiten und die Einfügeoperationen selbst schreiben. Dabei musst Du sowas wie Insert unterbinden.
Ein Dictionary ist auch nicht sortiert, ermöglicht nur direkten Zugriff. |
AW: Ich habe eine Liste, und die soll bitte immer sortiert sein
DeineTable.Sort := '[DEIN_NAME]';
|
AW: Ich habe eine Liste, und die soll bitte immer sortiert sein
Zitat:
|
AW: Ich habe eine Liste, und die soll bitte immer sortiert sein
Zitat:
Dafür sollte immer ein indexbasierter Zugriff benutzt werden. Ich selbst habe dafür schlicht ToArray überschrieben und gebe die Einträge dort sortiert zurück, wenn eine eigene Property SortedArray gesetzt ist. |
AW: Ich habe eine Liste, und die soll bitte immer sortiert sein
Da ist eine automatisch sortierende List-Klasse
Delphi-Quellcode:
Wonach sortiert wird, kann bei der Erstellung durch Angabe des
unit SortedList;
interface uses System.Generics.Collections; type TSortedList<T> = class( TList<T> ) protected procedure Notify( const Item : T; Action : TCollectionNotification ); override; end; implementation { TSortedList<T> } procedure TSortedList<T>.Notify( const Item : T; Action : TCollectionNotification ); begin inherited; if Action = cnAdded then Sort; end; end.
Delphi-Quellcode:
angegeben werden.
IComparer<T>
|
AW: Ich habe eine Liste, und die soll bitte immer sortiert sein
Danke für all die Antworten soweit :-)
In jedem OnNotify zu sortieren wollte ich eigentlich vermeiden: Angenommen ich werfe mittels AddRange(..) oder ähnlichem eine Menge an n zusätzlichen Elementen in den Topf - Dann sortiert er n mal, obwohl er es nur einmal müsste. Dunkel fällt mir noch die Magie von aspektorientierter Programmierung ein, damit habe ich allerdings Null Erfahrung und die Theorie mittlerweile auch wieder vergessen. Könnte man mit dem komischen ![]() |
AW: Ich habe eine Liste, und die soll bitte immer sortiert sein
Delphi-Quellcode:
Die auch noch überschreiben, da rein ein
procedure InsertRange(Index: Integer; const Values: array of T); overload;
procedure InsertRange(Index: Integer; const Collection: IEnumerable<T>); overload; procedure InsertRange(Index: Integer; const Collection: TEnumerable<T>); overload;
Delphi-Quellcode:
gefolgt vom
inherited;
Delphi-Quellcode:
und natürlich, während des inherited, die Sortierung vom Notify deaktivieren.
Sort;
Und vergiß nicht, beim Aufruf von
Delphi-Quellcode:
, den gewünschten Comparer anzugeben, wenn dir die Standardsortierung nicht gefällt.
TList<T>.Create
|
Alle Zeitangaben in WEZ +1. Es ist jetzt 14:42 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz