1

I want to use one keys for two values in Delphi some thing like this

TDictionary<tkey, tfirstvalue,tsecondvalue>;
Alec
  • 569
  • 2
  • 17
  • 27
  • What's stopping you from using a Tuple as key? – MechMK1 Dec 31 '17 at 20:05
  • is used in c# netfram 4 but I want in delphi – Newbie Tester Dec 31 '17 at 20:09
  • 3
    What about using a dynarray as value for the key? Or a record with two values? Then it becomes someting like `TDictionary`, which should be doable. or use a `TPair` as value type (which amounts to the 2 type record anyway). – Rudy Velthuis Jan 02 '18 at 12:11
  • 1
    @DavidStockinger: Delphi does not have built-in tuples. They can easily be emulated using other available data types, but they don't exist as built-in types. – Rudy Velthuis Jan 02 '18 at 12:13
  • In other words, the values can easily be combined as one single type (containing several values), in several ways. The TValue part can be as large as you need, so you can have 1:1 and 1:many relations. It only gets hairy if you want to have different key types, or multiple keys per value (many:many), or some such, because TDictionary is not made for that. – Rudy Velthuis Jan 02 '18 at 12:30

3 Answers3

2

Put your values into a compound structure like a record. Then use that record type as your dictionary value type.

David Heffernan
  • 601,492
  • 42
  • 1,072
  • 1,490
1

Delphi has not Tuple type. I don't know your purpose but may dynamic array of record type help.

Type
Tdict_ = reocord
 tkey:integer;
tfirstvalue,Tsecondvalue :string;
end;
var
Tdict:array of tdict_
...
procedure adddata(Tkey:integer;tfirstvalue:string;Tsecondvalue :string); 
begin
     setlength(tdict,length(tdict)+1);
    tdict[length(tdict)-1].tkey:=tkey;
    tdict[length(tdict)-1].tfirstvalue:=tfirstvalue;
    tdict[length(tdict)-1].tsecondtvalue:=tsecondvalue;    
end;

but you must write your own "find" function for return index of array .

for example

    Function find(tkey:integer):integer;
    var i:Integer;
    begin
     for i:=0 to length(Tdict)-1 do
     if tdict[i].tkey=i then
       begin
        result:=i;
        break;
       end;
    end;

    Function deletecalue(tkey:integer):integer;
    var i,j:Integer;
    begin
     i:=find(tkey)
        for j:=i to length(Tdict)-2 do
           tdict[j]:=tdict[j+1];
        setlength(tdict,length(tdict)-1);

    end;

if keys are strings type must be changed, but it will be slow for huge date .

Also read This: https://github.com/malcolmgroves/generics.tuples

Shahram Banazadeh
  • 500
  • 1
  • 5
  • 15
0

TDictionary<TKey, TPair<TFirstValue, TSecondValue>>, as @RudyVelthuis commented, is possible and works. However, TPair (found in System.Generics.Collections) is not meant for that - the two values are named Key and Value, which doesn't make sense here. We should make a copy of TPair, which could be named TTuple.

You can then do MyDictionary.Add('key', TTuple<string, string>.Create('firstvalue', 'secondvalue'));

Since it is implemented as a record (value type), there is no need to free it.

maf-soft
  • 2,335
  • 3
  • 26
  • 49