4

I am learning Pascal and currently stuck with a problem concerning array manipulation. I have come across a method of setting arrays, that I have seen in other languges, but I do not know how to do something similar in Pascal.

The declaration of the variable looks something like this:

rotationBounds: array of array of integer;
setLength(rotationBounds, 5, 5);

And I want to do something like this:

 rotationBounds :=
         [
          [0, 0, 0, 0, 0],
          [0, 1, 1, 0, 0],
          [0, 0, 1, 0, 0],
          [0, 0, 1, 1, 0],
          [0, 0, 0, 0, 0],
         ]; 

Basically, I am trying to set a multi-dimentional array directly, rather than looping through it.

One of my focuses is to make it look like a picture, easy to read and understand.

Is there a way I could achieve something like this?

I am using Borland Delphi 6 to compiler the progam.

David Heffernan
  • 601,492
  • 42
  • 1,072
  • 1,490
Rasteril
  • 605
  • 1
  • 5
  • 16
  • Not enough information. Is the array a variable, or a constant? Is it static or dynamic? What version of Pascal/Delphi/FPC? (Features supported vary.) – Ken White May 04 '13 at 15:01
  • If you need a matrix, dynamic array of dynamic array is overkill, since type of all elements have to be the same and matrix has to be rectangular (with notable exception of sparse matrices and few of its applications) – OnTheFly May 04 '13 at 21:37

3 Answers3

3

In Delphi 6 there is no built in support for dynamic array initialization. I'd use a pair of helper functions for this:

type
  TIntegerArray = array of Integer;
  TIntegerMatrix = array of TIntegerArray;

function IntegerArray(const Values: array of Integer): TIntegerArray;
var
  i: Integer;
begin
  SetLength(Result, Length(Values));
  for i := 0 to high(Result) do
    Result[i] := Values[i];
end;

function IntegerMatrix(const Values: array of TIntegerArray): TIntegerMatrix;
var
  i: Integer;
begin
  SetLength(Result, Length(Values));
  for i := 0 to high(Result) do
    Result[i] := Values[i];
end;

And then call it like this:

var
  rotationBounds: TIntegerMatrix;
....
rotationBounds := IntegerMatrix([
  IntegerArray([0, 0, 0, 0, 0]),
  IntegerArray([0, 1, 1, 0, 0]),
  IntegerArray([0, 0, 1, 0, 0]),
  IntegerArray([0, 0, 1, 1, 0]),
  IntegerArray([0, 0, 0, 0, 0]),
]);
David Heffernan
  • 601,492
  • 42
  • 1,072
  • 1,490
2

You can use it with ( in variable declarations

const temp: array[1..5, 1..5] of integer = (
   (0,0,0,0,0),
   (0,1,1,0,0),
   (0,0,1,0,0),
   (0,0,1,1,0),
   (0,0,0,0,0)
   );

and then

rotationBounds := temp;

If you have a dynamical array, you can write your own functions: Either row by row:

procedure setrow(var a: array of integer; b: array of integer);
begin
  if length(a) <> length(b) then raise Exception.Create('Invalid size');
  move(b[0], a[0], length(a) * sizeof(a[0]));
end;  

setrow(a[0], [0,0,0,0,0]);
setrow(a[1], [0,1,1,0,0]);
setrow(a[2], [0,0,1,0,0]);
setrow(a[3], [0,0,1,1,0]);
setrow(a[4], [0,0,0,0,0]);

Or all together:

type TIntArrayArray = array of array of integer;
procedure setall(var a: TIntArrayArray; b: array of integer);
var
  i: Integer;
begin
  if (length(a)*length(a[0]) <> length(b)) then raise Exception.Create('Invalid size');
  for i:= 0 to high(a) do
    move(b[i*length(a[0])], a[i,0], length(a[0]) * sizeof(a[0,0]));
end;              

setall(a, [0,0,0,0,0,
           0,1,1,0,0,
           0,0,1,0,0,
           0,0,1,1,0,
           0,0,0,0,0]);  
BeniBela
  • 16,412
  • 4
  • 45
  • 52
  • Can I use this method after the array has been created? It's a dynamic array of array of integer; – Rasteril May 04 '13 at 15:02
  • @Rasteril: what compiler are you using? In FPC trunk and recent Delphi you can use dynamic array constructor (http://wiki.freepascal.org/FPC_New_Features_Trunk#Dynamic_array_constructors) – LeleDumbo May 04 '13 at 15:03
  • I am using Borland Delphi 6, I am not sure what compiler that could be. Is there a way I could find out? – Rasteril May 04 '13 at 15:06
  • That would be the Borland Delphi 6 compiler. :-) – Ken White May 04 '13 at 15:09
  • 1
    Using a statical array, or a one-dimensional array (with 25 elements) is usually more efficient. With the 2d array, you can just write your own functions. See edit – BeniBela May 04 '13 at 15:48
  • Static arrays are indeed much more clean and concise, since matrices seldom require resizing. However, I do not agree what unwound dynamic array are more efficient. Second dimension is only a matter of convenience, since n×m sized matrix internal layout is exactly the the same as vector of n*m size. Personally, I'd go static and typed constant way. – OnTheFly May 04 '13 at 16:24
  • @user539484 If you use array of array, it creates n independent m-sized arrays, and then stores pointer to them in an n sized array – BeniBela May 04 '13 at 21:18
  • @BeniBela, yes, you are right. And this is another point for static and against dynamic matrices (TypeInfo must be common for all elements, as long as row Length's). – OnTheFly May 04 '13 at 21:34
1

Delphi 6 didn't support any other means of initializing dynamic arrays other than looping, so you're out of luck.

More recent versions of Delphi support a constructor-type initialization:

type
  TIntArray = array of Integer;

var
  IntArray: TIntArray;
begin
  IntArray := TIntArray.Create(0, 0, 1, 1, 0, 0, 1, 0, 0);
Ken White
  • 123,280
  • 14
  • 225
  • 444