![]() |
Duplicate Values in TDictionary
hier ein kurzer Testcode
Delphi-Quellcode:
unit Unit1xxx;
interface uses Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics, generics.collections, Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.StdCtrls; type TElement = class name: string; id: integer; value: string; constructor create(aname: string; aid: integer); end; TFrequencyList = class data: array of integer; constructor create(n: integer); end; type TForm1 = class(TForm) btn1: TButton; procedure btn1Click(Sender: TObject); private { Private-Deklarationen } public { Public-Deklarationen } end; var Form1: TForm1; implementation {$R *.dfm} procedure TForm1.btn1Click(Sender: TObject); var dict: TDictionary<TElement, TFrequencyList>; Myelement: TElement; FCount: TFrequencyList; begin dict := TDictionary<TElement, TFrequencyList>.create; /// code version #1 Myelement := TElement.create('maier', 0); FCount := TFrequencyList.create(6); FCount.data[1] := 99; dict.Add(Myelement, FCount); /// code version #2 dict.Add(Myelement.create('mueller', 1), FCount.create(5)); // Find some key Myelement := TElement.create('maier', 99); if dict.TryGetValue(Myelement, FCount) then begin ShowMessage('Found it!: ' + IntToStr(FCount.data[1])); end; Myelement := TElement.create('maier', 0); if dict.TryGetValue(Myelement, FCount) then begin ShowMessage('Found it!: ' + IntToStr(FCount.data[1])); end; end; { TFrequencyList } constructor TFrequencyList.create(n: integer); begin setlength(data, n); end; { TElement } constructor TElement.create(aname: string; aid: integer); begin self.name := aname; self.id := aid; self.value := 'dummy data'; end; end. Delphi behauptet beim Einfügen des zweiten Datensatzes "Duplicate nicht zulässig" , ich sehe den Fehler nicht .... |
AW: Duplicate Values in TDictionary
Von
Delphi-Quellcode:
Nach
/// code version #2
dict.Add(Myelement.create('mueller', 1), FCount.create(5));
Delphi-Quellcode:
ändern!
/// code version #2
dict.Add(TElement.create('mueller', 1), FCount.create(5)); |
AW: Duplicate Values in TDictionary
Warum die Meldung mit den Duplikaten kommt kann ich dir nicht sagen, aber ein Objekt als Key zu nehmen ist nicht so praktisch. Vor allem kannst du auf die Weise nicht überprüfen ob ein Objekt schon in der Liste enthalten ist.
Denn die Objekte sind nur Pointer (Zahlen) und dieser Pointer ist grob gesagt für jedes Objekt unterschiedlich, selbst wenn die Daten des Objekts identisch sind. Damit das funktioniert musst du nach EXAKT dem Objekt suchen was du beim Add angegeben hast, nicht einer Kopie mit denselben Werten. @TiGü: Stimmt. Aber statt FCount.Create muss da auch TFrequencyList.Create stehen. |
AW: Duplicate Values in TDictionary
Hallo,
mit
Code:
änderst du nur die Instanz Myelement. Das hat Auswirkungen auf alle Stellen, an denen du mit genau dieser Instanz arbeitest, also auch auf den Schlüssel im Dictionary. Deswegen auch die Fehlermeldung, dass der Schlüssel schon exisitert. Um ein weiteres Wertepaar ins Dictionary einzutragen, solltest du zwei neue Instanzen erstellen mit
Myelement.create('mueller', 1)
Code:
Danach erstellst du zwei neue Instanzen mit:
dict.Add(Telement.create('mueller', 1), TFrequencyList.create(5));
Code:
Myelement := TElement.create('maier', 99);
Code:
Diese Instanzen werden natürlich nicht im Dictionary gefunden, da si nicht eingefügt wurden. Selbst wenn du die Zeile rausnimmst, die den Fehler verursacht, werden die neuen Instanzen nicht im Dictionary gefunden. Auch wenn die gleichen Werte in der Klasse gespeichert sind, so handelt es sich dennoch um zwei unterschiedliche Instanzen. Um Instanzen mit gleichen Werten zu vergleichen musst du einen eigenen Comparer schreiben und beim Erstellen des Dictionary mitgeben.
Myelement := TElement.create('maier', 0);
|
AW: Duplicate Values in TDictionary
Zitat:
|
AW: Duplicate Values in TDictionary
Problem #1 mit den Duplikaten ist gelöst; Verbleibt die Frage warum er Die Elemente dann nicht in meinem Wörterbuch findet ?
Delphi-Quellcode:
dict: TDictionary<TElement, TFrequencyList>;
Myelement: TElement; FCount: TFrequencyList; begin dict := TDictionary<TElement, TFrequencyList>.create; /// code version #1 Myelement := TElement.create('maier', 0); FCount := TFrequencyList.create(6); FCount.data[1] := 99; dict.Add(Myelement, FCount); /// code version #2 dict.Add(Telement.create('mueller', 1), TFrequencyList.create(5)); // Find some key -> hier sollte man nix finden .... Myelement := TElement.create('maier', 99); if dict.TryGetValue(Myelement, FCount) then begin ShowMessage('Found it!: ' + IntToStr(FCount.data[1])); end; /// gibt den hier gibt es doch :-( ???????????????????????? Myelement := TElement.create('maier', 0); if dict.TryGetValue(Myelement, FCount) then begin ShowMessage('Found it!: ' + IntToStr(FCount.data[1])); end; end; |
AW: Duplicate Values in TDictionary
Zitat:
|
AW: Duplicate Values in TDictionary
Zitat:
Delphi-Quellcode:
und alle Ableitungen ganz simpel über die Referenz geht.
TObject
Und unterschiedliche Instanzen haben auch unterschiedliche Referenzen. Also musst du dem Dictionary einen Comparer mitgeben, der auf deine gewünschte Gleichheit prüft. |
AW: Duplicate Values in TDictionary
ich habe einen TCustomComparer erstellt, nur bekomme ich einen ABSTRAKTEN Fehler beim Einfügen des zweiten Datensatzes in mein TDictionary
Delphi-Quellcode:
type
TElement = class name: string; id: integer; value: string; constructor create(aname: string; aid: integer); end; TFrequencyList = class data: array of integer; constructor create(n: integer); end; TMyComparer = class(TCustomComparer<TElement>) function Compare(const Left, Right: TElement): integer; override; end; type TForm1 = class(TForm) btn1: TButton; procedure btn1Click(Sender: TObject); private { Private-Deklarationen } public { Public-Deklarationen } end; var Form1: TForm1; implementation {$R *.dfm} procedure TForm1.btn1Click(Sender: TObject); var dict: TDictionary<TElement, TFrequencyList>; Myelement: TElement; FCount: TFrequencyList; begin dict := TDictionary<TElement, TFrequencyList>.create( TMyComparer.create) ; /// code version #1 Myelement := TElement.create('maier', 0); FCount := TFrequencyList.create(6); FCount.data[1] := 99; dict.Add(Myelement, FCount); /// code version #2 dict.Add(TElement.create('mueller', 1), TFrequencyList.create(5)); // Find some key -> sollten nix finden Myelement := TElement.create('maier', 99); if dict.TryGetValue(Myelement, FCount) then begin ShowMessage('Found it!: ' + IntToStr(FCount.data[1])); end; /// gibt es doch :-( Myelement := TElement.create('maier', 0); if dict.TryGetValue(Myelement, FCount) then begin ShowMessage('Found it!: ' + IntToStr(FCount.data[1])); end; end; { TFrequencyList } constructor TFrequencyList.create(n: integer); begin setlength(data, n); end; { TElement } constructor TElement.create(aname: string; aid: integer); begin self.name := aname; self.id := aid; self.value := 'dummy data'; end; { TMyComparer } function TMyComparer.Compare(const Left, Right: TElement): integer; begin result := Comparetext(left.name, right.name); end; end. |
AW: Duplicate Values in TDictionary
Du musst für deinen Comparer die Methoden Compare,Equals und GetHashCode überschreiben. Nur Compare reicht nicht.
|
Alle Zeitangaben in WEZ +1. Es ist jetzt 11:14 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