Reputation: 2710
I want to make a data structure like multidimensional associative array in Delphi.
I know that there is TObjectDictionary
. But making multidimensional array with TObjectDictionary is so hard and not efficient I think.
Is there any other good approach to make multidimensional associative array in Delphi?
Upvotes: 0
Views: 761
Reputation: 3432
TDictionary is hash-based, so performance will not seriously degrade for any number of dimensions. Two-dimensional version of dictionary can be implementation like this:
T2DimDictionary<TDim1,TDim2,TValue> = class
private
function GetValue(x: TDim1; y: TDim2): TValue;
procedure SetValue(x: TDim1; y: TDim2; const Value: TValue);
protected
FDictionary: TObjectDictionary<TDim1, TDictionary<TDim2, TValue>>;
public
constructor Create;
destructor Destroy; override;
property Values[x: TDim1; y: TDim2]: TValue read GetValue write SetValue; default;
end;
{ T2DimDictionary }
constructor T2DimDictionary<TDim1,TDim2,TValue>.Create;
begin
FDictionary := TObjectDictionary<TDim1, TDictionary<TDim2, TValue>>.Create;
end;
destructor T2DimDictionary<TDim1,TDim2,TValue>.Destroy;
begin
FreeAndNil(FDictionary);
inherited;
end;
function T2DimDictionary<TDim1,TDim2,TValue>.GetValue(x: TDim1; y: TDim2): TValue;
var
SubArray: TDictionary<TDim2, TValue>;
begin
if not FDictionary.TryGetValue(x, SubArray) or
not SubArray.TryGetValue(y, result)
then
raise exception.Create('Error');
end;
procedure T2DimDictionary<TDim1,TDim2,TValue>.SetValue(x: TDim1; y: TDim2;
const Value: TValue);
var
SubArray: TDictionary<TDim2, TValue>;
begin
if not FDictionary.TryGetValue(x, SubArray) then
begin
SubArray := TDictionary<TDim2, TValue>.Create;
FDictionary.Add(x, SubArray);
end;
SubArray.AddOrSetValue(y, Value);
end;
var
d: T2DimDictionary<integer, string, string>;
begin
d := T2DimDictionary<integer, string, string>.Create;
d[1,'january'] := 'test1';
d[1,'march'] := 'test2';
assert(d[1,'january']='test1');
FreeAndNil(d);
end;
Alternatively you can use single TDictionary with complex key based on all "dimensions".
Upvotes: 5