Einzelnen Beitrag anzeigen

r2c2

Registriert seit: 9. Mai 2005
Ort: Nordbaden
925 Beiträge
 
#1

TDictionary - ein Wörterbuch

  Alt 3. Jan 2006, 15:40
Hallo DPler
jetzt hab ich auch mal was für die CodeLibrary. Was Welterschütterndes hab ich zwar nicht, aber praktisch könnte es u.U. trotzdem sein:
Manchmal braucht man ja sowas, wie n Wörterbuch. Man hat n string und will dem n anderen string zuordnen. Möglich war das die ganze Zeit auch schon.Es gab dafür auch mehrere Möglichkeiten:
a) ne StringList und die zugeordneten strings in die Objects schreiben ==> Nachteil: TypeCasts und Pointer erforderlich
b) 2 StringListen ==> Nachteil: Wollte man irgendwie etwas mit der Liste anstellen, so musste man das mit beiden Listen synchron machen; und wehe man hat irgendwo nicht richtig aufgepasst...
c) Array of Record ==> Nachteil: Keine OOP, keine vordefinierten Methoden, Speicherverwaltung von Hand zu machen...
d) ObjectList of Class ==> Nachteil: TypeCasts
e) TList of Record ==> Nachteil: TypeCast, Pointer, Speicherverwaltung
f) Verkettete Listen ==> Nachteil: viel Arbeit
g) ...

Irgendwie war das alles nix. Also bastelt man sich mal ne Klasse, die einem die lästigen und fehlerträchtigen TypeCasts erspart: TDictionary

Was kann das Viech nun alles?
Hier mal n Auszug aus der Unit - der public-Teil:
Delphi-Quellcode:
  public
    constructor Create;
    destructor Destroy; override;
    property Count: Integer read GetCount;
    property Items[index: Integer]: TDicData read GetItem write SetItem;
    property Keys[index: Integer]: string read GetKey write SetKey;
    property SectionName: string read FSectionName write FSectionName;
    property Sorted: Boolean read FSorted write SetSorted default False;
    property Values[Key: string]: string read GetValue write SetValue; default; // bei der D6-Version heißt diese property "ValuesStr" und ist nicht default
    property Values[index: Integer]: string read GetValue write SetValue; default;
    function Add(const AKey, AValue: string): Integer;
    procedure Clear; virtual;
    procedure Delete(const AKey: string); overload; virtual;
    procedure Delete(const AIndex: Integer); overload; virtual;
    function DeleteValue(const AValue: string): Integer; virtual;
    procedure Exchange(const Index1, Index2: Integer); overload; virtual;
    procedure Exchange(const Key1, Key2: string); overload; virtual;
    function First: TDicData; virtual;
    function IndexOf(const AKey: string): Integer; virtual;
    function IndexOfValue(const AValue: string): Integer; virtual;
    procedure Insert(const AKey, AValue: string; const APos: Integer); virtual;
    function Last: TDicData; virtual;
    procedure LoadFromFile(const AFileName: string); virtual;
    procedure Move(const AIndex, ANewIndex: Integer); virtual;
    procedure SaveToFile(const AFileName: string); virtual;
  end;
Das Meiste sollte selbsterklärend sein. N paar Anmerkungen trotzdem noch:
- LoadFromFile und SaveToFile speichert/lädt eine Ini-Datei
- SectionName bildet hierbei den Namen für die Section; [Data] ist default
- Ein Key-string kann nur einmal vorkommen; wird versucht zweimal unter dem selben Key etwas zu speichern, wird der vorhandene Wert ersetzt
- objlist_tmpl.pas und jedi.inc werden benötigt(siehe hierzu diesen Thread)

Versionshinweise:
Delphi 2005 unterstützt das Überladen von properties(keine Ahnung, ob D7 das auch schon tut ), deshalb gibt es eine Version für Delphi2005(mit überladener property Values) und eine Delphi6-Version, bei der die property Values, die den Key-String entgegennimmt, "ValuesStr" heißt...

Und noch n bisschen Beispiel-Code:
Delphi-Quellcode:
var
  Dic: TDictionary;
begin
  Dic := TDictionary.Create;
  try
    Dic.Add('house', 'Haus');
    Dic.Add('pupil', 'Schüler');
    Dic.Add('biro', 'Kugelschreiber');
    Dic.Add('Screen', 'Bildschirm');
    Dic.Add('insert', 'einfügen');
    Memo1.Lines.Add(Dic.Values['Screen']); // Value über Key
// Memo1.Lines.Add(Dic.ValuesStr['Screen']); // Value über Key; D6-Version
    Memo1.Lines.Add(Dic['Screen']); // Value über Key per default-property; bei D6 nicht möglich
    Memo1.Lines.Add(Dic[3]); // Value über Index per default-property
    Memo1.Lines.Add(Dic.Values[1]); // Value über Index
    Memo1.Lines.Add(Dic.Keys[0]); // Key über Index
    Memo1.Lines.Add(Dic.Items[2].Value); // Item über Index
    Memo1.Lines.Add(Dic.Items[4].Key); // Item über Index
  finally
    Dic.Free;
  end;
Getestet unter:
- D6PE
- D2005PE

Danke:
Dank gebührt u.a.:
- alcaeus für die objlist_tmpl.pas
- Thomas Mueller für den Artikel Object Pascal Templates
- allen anderen, die sich angesprochen fühlen...

rfc

Christian

[edit=Chakotay1308]URL-Tags korrigiert. Mfg, Chakotay1308[/edit]
[edit=Chakotay1308]Anhang aktualisiert. Mfg, Chakotay1308[/edit]
Angehängte Dateien
Dateityp: pas dictionary_class_918.pas (14,3 KB, 130x aufgerufen)
Dateityp: pas dictionary_class_d6_158.pas (14,3 KB, 140x aufgerufen)
Kaum macht man's richtig, schon klappts!
  Mit Zitat antworten Zitat