![]() |
Sortierte TObjectList - Einträge richtig einfügen
Ich habe eine sortierte TObjectList in einer eigenen Klasse. Ich muss nun feststellen, ob ein bestimmtes Element bereits in der Liste vorhanden ist und - wenn nicht - es an der richtigen Stelle einfügen.
Ich habe mir dazu eine quasi aufgebohrte Version von IndexOf mit einer binären Suche gebastelt, die mir bei Nichtfinden in p die richtige Einfügeposition zurückmeldet:
Delphi-Quellcode:
Jetzt hätte ich dazu einige Fragen:
type
TZiel = class(TObject) WERT1 : Word; WERT2 : Word; WERT3 : String; WERT4 : String; WERT5 : Cardinal; WERT6 : Int64; WERT7 : Int64; end; TZielListe = class(TObjectList) function TZielListe.WertGefunden(Wert:string;var WertPos:Integer):Boolean; var p, Anz, MWert: Integer; begin // WertPos ist entweder die Position des gefundenen Wertes oder die Einfügeposition in die sortierte Liste, falls nicht gefunden WertPos := 0; If Self.Count = 0 then exit(False); p := 0; Anz := Self.Count; while p < Anz do begin MWert := p + (Anz - p) div 2; if Self[MWert].Wert3 = Wert then begin WertPos := MWert; Exit(True); end; if AnsiCompareText(Wert,Self[MWert].Wert3) = -1 then Anz := MWert else p := MWert + 1; end; If (p = Anz) or (AnsiCompareText(Wert,Self[p].Wert3) > 0) then WertPos := p else WertPos := Max(0,p - 1); Result := False; end;
Danke! |
AW: Sortierte TObjectList - Einträge richtig einfügen
Welche Delphi-Version nutzt Du denn?
(Solltest Du mal in Deinem Profil einstellen.) Wenn es eine aktuelle mit Generics und einem TComparer ist dann wird das Ganze vielleicht etwas einfacher zu lösen sein. Ein Bsp. mal hier: ![]() |
AW: Sortierte TObjectList - Einträge richtig einfügen
Ja, wollt ich schon immer mal einstellen, ist hiermit geschehen. D2009. Generics gibts also, aber BinarySearch und TComparer offenbar noch nicht.
|
AW: Sortierte TObjectList - Einträge richtig einfügen
Doch in der Unit
Delphi-Quellcode:
Generics.Defaults
|
AW: Sortierte TObjectList - Einträge richtig einfügen
In der Tat!
Aber ach, Generics... ! MUSS DAS SEIN? Ich weiß natürlich, für die meisten hier sind das Pheromone... |
AW: Sortierte TObjectList - Einträge richtig einfügen
Muss nicht sein.
Aber gerade für typisierte Listen ist das ganz komfortabel. Die ganzen anderen Schweinereien mit generischen Klassen usw. vermeide ich auch lieber. Aber generische Listen sind schon nett (und unkompliziert). Lediglich das schrittweise debuggen ist dann etwas seltsam (m.E.). |
AW: Sortierte TObjectList - Einträge richtig einfügen
Auf der anderen Seite liefert BinarySearch so ziemlich genau das, was ich will:
Zitat:
Zitat:
Vielleicht noch eine Idee zu den anderen Fragen? |
AW: Sortierte TObjectList - Einträge richtig einfügen
Gute Entscheidung. :thumb:
Generische Listen werden Dir hier helfen. Du musst nur einen TComparer definieren, der Dir kleiner, gleich oder größer zu Deinen Items zurück liefert. Den Rest kannst Du der Binärsuchfunktion überlassen. Eine Neusortierung musst Du eigentlich gar nicht machen, da Du jeden Eintrag direkt an die passende Stelle einsortieren kannst. (Im Nachhinein bin ich nur nicht sicher, ob Extract aus meinem Beispiel vorhin die binäre Suche benutzt. Sonst müsste man eben explizit binär suchen und den Eintrag an dem gefundenen Index entfernen.) Für unterschiedliche Sortierungen (nach Eigenschaft A oder B) habe ich keine Lösung parat. Man könnte den Comparer unterschiedlich steuern (case ... of) und müsste die Liste dann aber bei einer Umschaltung komplett umsortieren. Oder man verwaltet mehrere Listen mit Objektreferenzen und sortiert die binär verschieden. Muss man halt immer alle synchron halten und Einträge immer in allen einfügen bzw. entfernen. Die beste Lösung hängt sicher vom Einzelfall ab. Wenn man sich eine Factory baut, die das Einfügen und Entfernen zentral übernimmt, kann die das synchronisieren der Listen natürlich schön automatisieren. Ganz nützlich kann auch ein Dictionary sein, was idR. noch schneller als eine binäre Liste funktioniert. Zu Listentypen will ich gleich nochmal auf meinen kürzlichen Link zu Video2Brain verweisen ... hierin: ![]() Die Trainerin fasst das m.E. ganz gut zusammen. |
AW: Sortierte TObjectList - Einträge richtig einfügen
Delphi-Quellcode:
uses
Generics.Collections, Generics.Defaults; type TZiel = class(TObject) WERT1 : Word; WERT2 : Word; WERT3 : String; WERT4 : String; WERT5 : Cardinal; WERT6 : Int64; WERT7 : Int64; end; TZielListe = class( TObjectList<TZiel> ) private function Compare( const L,R: TZiel) : Integer; public constructor Create( OwnsObjects: Boolean = true ); end; function TZielListe.Compare( const L,R: TZiel) : Integer; begin Result := TComparer<string>.Default.Compare( L.Wert3, R.Wert3 ); end; constructor TZielListe.Create( OwnsObjects: Boolean ); begin inherited Create( TComparer<TZiel>.Construct( Compare ), OwnsObjects ); end; |
AW: Sortierte TObjectList - Einträge richtig einfügen
Danke euch beiden! Sensationell.
Schließe mich dem an: Kaum macht man's richtig - schon funktioniert's. :thumb: |
Alle Zeitangaben in WEZ +1. Es ist jetzt 21:55 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