Delphi Extract from TObjectDictionary

code exchange for this question as a reference: Delphi TPair Exception

How can I get the key and value from a specific TObjectDictionary entry without using TPair and without retrieving / removing / removing a pair from the list?

{$APPTYPE CONSOLE} uses SysUtils, Generics.Defaults, Generics.Collections; type TProduct = class private FName: string; procedure SetName(const Value: string); published public property Name: string read FName write SetName; end; type TListOfProducts = TObjectDictionary<TProduct, Integer>; { TProduct } procedure TProduct.SetName(const Value: string); begin FName := Value; end; var MyDict: TListOfProducts; MyProduct1: TProduct; MyProduct2: TProduct; MyProduct3: TProduct; APair: TPair<TProduct, Integer>; aKey: string; begin try MyDict := TListOfProducts.Create([doOwnsKeys]); MyProduct1 := TProduct.Create; MyProduct1.Name := 'P1'; MyProduct2 := TProduct.Create; MyProduct2.Name := 'P2'; MyProduct3 := TProduct.Create; MyProduct3.Name := 'P3'; MyDict.Add(MyProduct1, 1); MyDict.Add(MyProduct2, 2); MyDict.Add(MyProduct3, 3); //the code to look for a **concrete product** (ie: MyProduct1) goes here.. Readln; except on E: Exception do Writeln(E.ClassName, ': ', E.Message); end; end. 

Thanks.

===========================

= Answer Code =

 {$APPTYPE CONSOLE} uses SysUtils, Generics.Defaults, Generics.Collections; type TProduct = class private FName: string; procedure SetName(const Value: string); published public property Name: string read FName write SetName; end; type TListOfProducts = TObjectDictionary<TProduct, Integer>; { TProduct } procedure TProduct.SetName(const Value: string); begin FName := Value; end; var MyDict: TListOfProducts; MyProduct1: TProduct; MyProduct2: TProduct; MyProduct3: TProduct; MySearchedProduct: TProduct; // From Answer. APair: TPair<TProduct, Integer>; aProductName: string; begin try MyDict := TListOfProducts.Create([doOwnsKeys]); MyProduct1 := TProduct.Create; MyProduct1.Name := 'P1'; MyProduct2 := TProduct.Create; MyProduct2.Name := 'P2'; MyProduct3 := TProduct.Create; MyProduct3.Name := 'P3'; MyDict.Add(MyProduct1, 1); MyDict.Add(MyProduct2, 2); MyDict.Add(MyProduct3, 3); Writeln('Enter the Product Name to search: '); //the code to look for a **concrete product** goes here.. Readln(aProductName); for MySearchedProduct in Mydict.Keys do if (MySearchedProduct.Name = aProductName) then break; if MySearchedProduct.Name = aProductName then WriteLn('I have found the product: ' + MySearchedProduct.Name) else WriteLn('I have not found a product with that name.'); Readln; except on E: Exception do Writeln(E.ClassName, ': ', E.Message); end; end. 
+6
source share
3 answers

You can use the Keys and Values MyDict properties.

In this loop:

 var MyProduct: TProduct; Value: Integer; begin for Value in MyDict.Values do writeln(Value); for MyProduct in MyDict.Keys do writeln(MyProduct.Name); 

Or by index using ToArray :

 writeln(MyDict.Keys.ToArray[1].Name); writeln(MyDict.Values.ToArray[1]); 
+4
source

Key and Value are stored in the dictionary as TPair<TKey,TValue> . If you need to work with a key and a value, the logical task is to use TPair ;

It looks like:

 for APair in MyDict do begin // Your stuff goes here. end; 

If for some reason you do not want to use TPair to extract pairs, you can use something like this, but it is absolutely not a good idea: you make a lot of dictionary queries without a good reason:

 for AKey in MyDict.Keys do begin AValue := MyDict[AKey]; // Do something with both AKey and AValue end; 
+4
source

Key cyclization can be overly slow if your dictionary contains many members. I suggest keeping the key paired with the real value. Given the above example, it might look like this:

 type TListOfProducts = TObjectDictionary<TProduct, TPair<TProduct,Integer>>; 
+1
source

Source: https://habr.com/ru/post/887169/


All Articles