Forum > General
multi-dimensional open array parameter?
taazz:
you do something along the lines of
--- Code: ---type
type
T2DIntArray = array of array of Integer;
procedure CallOnArray(var anArray:T2DIntArray);
begin
end;
procedure SetLength2D(var anArray:T2DIntArray; Dim1,Dim2:Integer);
var
vCntr : integer;
begin
SetLength(anArray,Dim1);
for vCntr := 0 to Dim1-1 do begin
SetLength(anArray[vCntr],Dim2);
end;
end;
procedure Test;
var
ar2 : T2dIntArray;
begin
SetLength2D(ar2,2,3);
callOnArray(ar2);
end;
--- End code ---
Leledumbo:
I suggest using container classes such as list instead of arrays for this. However, I don't think there's something built-in for this. So I end up writing this:
--- Code: ---{$mode objfpc}{$H+}
uses
fgl;
type
TIntegerList = class(specialize TFPGList<Integer>)
private
function GetIt(Index: Integer): Integer;
procedure PutIT(Index: Integer; const Item: Integer);
public
property Items[i: Integer]: Integer read GetIt write PutIt; default;
end;
TIntegerMatrix = class(specialize TFPGObjectList<TIntegerList>)
private
function GetIt(Index: Integer): TIntegerList;
public
constructor Create;
property Items[i: Integer]: TIntegerList read GetIt; default;
end;
{ TIntegerList }
function TIntegerList.GetIt(Index: Integer): Integer;
begin
if Index >= Count then Result := 0 else Result := Get(Index);
end;
procedure TIntegerList.PutIt(Index: Integer; const Item: Integer);
begin
if Index >= Count then Count := Index + 1;
Put(Index,Item);
end;
{ TIntegerMatrix }
constructor TIntegerMatrix.Create;
begin
inherited Create(true);
end;
function TIntegerMatrix.GetIt(Index: Integer): TIntegerList;
var
OldCount,i: Integer;
begin
if Index >= Count then begin
OldCount := Count;
Count := Index + 1;
for i := OldCount to Count - 1 do begin
Put(i,TIntegerList.Create);
end;
end;
Result := Get(Index);
end;
procedure ManipulateIntegerMatrix(m: TIntegerMatrix);
var
i,j: Integer;
begin
for i := 0 to m.Count - 1 do
for j := 0 to m[i].Count - 1 do
m[i][j] := -m[i][j];
end;
var
a: TIntegerMatrix;
i,j: Integer;
begin
a := TIntegerMatrix.Create;
a[0][0] := 1; a[0][1] := 2; a[0][2] := 3;
a[1][0] := 4; a[1][1] := 5; a[1][2] := 6;
a[2][0] := 7; a[2][1] := 8; a[2][2] := 9;
WriteLn('Before:');
for i := 0 to a.Count - 1 do begin
for j := 0 to a[i].Count - 1 do
Write(a[i][j]:3);
WriteLn;
end;
ManipulateIntegerMatrix(a);
WriteLn('After:');
for i := 0 to a.Count - 1 do begin
for j := 0 to a[i].Count - 1 do
Write(a[i][j]:3);
WriteLn;
end;
a.Free;
end.
--- End code ---
Note that my convention is no error shall be generated for accessing index outside existing ones. Instead, 0 shall be returned for inner index, while new TIntegerList instance will be returned for outer index. It's up to you whether to follow or change this.
photor:
Thanks for all the warm replies. But it is a pity that free pascal doesn't support multi-dimensional open array parameters. To me, extending the function of one-dimensional open array parameters to the multi-dimensional case is not a big challenge to the free pascal developers.
User137:
Was there something wrong with taazz code? I can give another example
--- Code: ---type
TArr = array of array of integer;
...
procedure Test(arr: TArr);
begin
arr[high(arr), high(arr[0])]:=1;
end;
procedure TForm1.FormCreate(Sender: TObject);
var arr: TArr;
begin
setlength(arr, 10, 20); // 10x20 matrix
arr[9, 19]:=0;
Test(arr);
caption:=inttostr(arr[9, 19]); // Sets caption 1
end;
--- End code ---
In nowhere did i tell Test() function that the matrix size was 10x20, but it could still modify the last value.
Leledumbo:
--- Quote from: photor on May 31, 2014, 12:17:50 pm ---Thanks for all the warm replies. But it is a pity that free pascal doesn't support multi-dimensional open array parameters. To me, extending the function of one-dimensional open array parameters to the multi-dimensional case is not a big challenge to the free pascal developers.
--- End quote ---
If you think so, then implement. Welcome to open source world.
Navigation
[0] Message Index
[#] Next page
[*] Previous page