### Bookstore

 Computer Math and Games in Pascal (preview) Lazarus Handbook

### Author Topic: array of array of type?  (Read 1192 times)

#### xixixi

• New Member
• Posts: 21
##### array of array of type?
« on: June 01, 2023, 10:59:51 pm »
How can I make a procedure accept a multidimensional open array? Here's what I tried; see the procedure Clear:

Code: Pascal  [Select][+][-]
1. program TestArrayOfArray;
2. {\$mode OBJFPC}
3. type
4.    Country = (Congo, Kenya, Tanzania);
5.    Animal  = (lion, giraffe, zebra);
6.    Biome   = (forest, rainforest, savannah);
7.
8.    TIntArr = array of integer;
9.    TIntArrArr = array of TIntArr;
10.
11.    TCxA = array [Country, Animal] of integer;
12.
13. var
14.    cxa: array [Country, Animal] of integer;
15.    cxa2: TCxA;
16.    cxb: array [Biome, Animal] of integer;
17.
18. procedure Clear (var a: { array of array of integer  (* 1 *) }
19.                         { array of TIntArr         (* 2 *) }
20.                          TIntArrArr               (* 3 *)
21.                      );
22. var
23.    i, j: integer;
24. begin
25.    for i := Low(a) to High(a) do
26.       for j := Low(a[i]) to High(a[i]) do
27.          a[i][j] := 0;
28. end;
29.
30. begin
31.    Clear(cxa);
32.    Clear(cxa2);
33.    Clear(cxb);
34. end.
35.

When I try 1 (array of array of integer), I get:
Code: [Select]
`taa.pas(18,34) Error: Type identifier expected                     taa.pas(18,34) Fatal: Syntax error, ")" expected but "ARRAY" found `
When I try 2 (array of TIntArr), I get:
Code: [Select]
`taa.pas(31,13) Error: Call by var for arg no. 1 has to match exactly: Got "Array[Country] Of Array[Animal] Of LongInt" expected "{Open} Array Of TIntArr"taa.pas(32,14) Error: Call by var for arg no. 1 has to match exactly: Got "TCxA" expected "{Open} Array Of TIntArr"taa.pas(33,13) Error: Call by var for arg no. 1 has to match exactly: Got "Array[Biome] Of Array[Animal] Of LongInt" expected "{Open} Array Of TIntArr"`
When I try 3 (TIntArrArr), I get:
Code: [Select]
`taa.pas(31,13) Error: Call by var for arg no. 1 has to match exactly: Got "Array[Country] Of Array[Animal] Of LongInt" expected "TIntArrArr"                                                                                                                          taa.pas(32,14) Error: Call by var for arg no. 1 has to match exactly: Got "TCxA" expected "TIntArrArr"                             taa.pas(33,13) Error: Call by var for arg no. 1 has to match exactly: Got "Array[Biome] Of Array[Animal] Of LongInt" expected "TIntArrArr"`
I thought the idea of "array of ..." parameters was that I can pass any array to them. What I'm doing wrong?
« Last Edit: June 02, 2023, 01:37:08 pm by xixixi »

#### jamie

• Hero Member
• Posts: 5680
##### Re: array of array of type?
« Reply #1 on: June 01, 2023, 11:57:06 pm »
is this home work or are you trying to do a bulk clear ?
The only true wisdom is knowing you know nothing

#### howardpc

• Hero Member
• Posts: 4144
##### Re: array of array of type?
« Reply #2 on: June 02, 2023, 12:30:44 am »
The following skeleton code compiles and "works" in some fashion.

However, I think var parameters for arrays do not always give the results you might expect, because there seem to be persistent values still displayed, and the chain of pocedures somehow is not fully executed. So there are bugs to be eliminated for sure.
Code: Pascal  [Select][+][-]
1. program TestArrayOfArray;
2.
3. {\$mode objfpc}{\$H+}
4. {\$IfDef windows} {\$AppType console} {\$EndIf}
5.
6. type
7.
8.    Country = (Congo, Kenya, Tanzania);
9.    Animal  = (lion, giraffe, zebra);
10.    Biome   = (forest, rainforest, savannah);
11.
12.
13.    TCxA = array [Country, Animal] of Integer;
14.    TCxB = array[Biome, Animal] of Integer;
15.
16. var
17.    cxa:  TCxA = ((0, 1, 2), (2, 3, 4), (5, 6, 7));
18.    cxa2: TCxA = ((10, 11, 12), (13,14,15), (16,17,18));
19.    cxb:  TCxB = ((100, 101, 102), (1010, 1020, 1030), (-1, -2, -3));
20.
21.
22. procedure DisplayA(aCxA: TCxA);
23. var
24.   a: Animal;
25.   c: Country;
26. begin
27.   for c := Low(aCxA) to High(aCxA) do
28.     begin
29.       WriteLn(c);
30.       for a := Low(aCxA[c]) to High(aCxA[c]) do
31.         Write(aCxA[c][a], ', ');
32.       WriteLn;
33.     end;
34. end;
35.
36. procedure DisplayB(aCxB: TCxB);
37. var
38.   a: Animal;
39.   b: Biome;
40. begin
41.   for b := Low(aCxB) to High(aCxB) do
42.     begin
43.       WriteLn(b);
44.
45.       for a := Low(aCxB[b]) to High(aCxB[b]) do
46.         Write(aCxB[b][a], ', ');
47.       WriteLn;
48.     end;
49. end;
50.
51. procedure ClearA (var aCxA: TCxA);
52. begin
53.   aCxA := Default(TCxA);
54. end;
55.
56. procedure ClearB (var aCxB: TCxB);
57. begin
58.    aCxB := Default(TCxB);
59. end;
60.
61. begin
62.    DisplayA(cxa);
63.    ClearA(cxa);
64.    WriteLn(#10'------- after ClearA');
65.    DisplayA(cxa);
66.
67.    DisplayA(cxa2);
68.    ClearA(cxa2);
69.    WriteLn(#10'------- after ClearA');
70.    DisplayA(cxa2);
71.
72.    DisplayB(cxb);
73.    ClearB(cxb);
74.    WriteLn(#10'------- after ClearB');
75.    DisplayB(cxb);
76.
78. end.

#### xixixi

• New Member
• Posts: 21
##### Re: array of array of type?
« Reply #3 on: June 02, 2023, 01:31:58 pm »
is this home work or are you trying to do a bulk clear ?

Neither, that's just a made up example. I want to know how to make open arrays work with multidimensional arrays.

#### xixixi

• New Member
• Posts: 21
##### Re: array of array of type?
« Reply #4 on: June 02, 2023, 01:36:40 pm »
The following skeleton code compiles and "works" in some fashion.

...

But you are repeating the same code for each index type, which is what I want to avoid, and what open arrays are supposedly meant to solve.

Even flattening the array would help me here, i.e., the procedure getting a unidimensional array of integer of length 9, if that were possible somehow.

#### DavidL

• New member
• Posts: 7
##### Re: array of array of type?
« Reply #5 on: June 02, 2023, 01:41:08 pm »
Perhaps arrays aren't the best fundamental type for this particular task?

#### Zvoni

• Hero Member
• Posts: 1936
##### Re: array of array of type?
« Reply #6 on: June 02, 2023, 01:48:19 pm »
But you are repeating the same code for each index type, which is what I want to avoid, and what open arrays are supposedly meant to solve.
Generics?

Quote
Even flattening the array would help me here, i.e., the procedure getting a unidimensional array of integer of length 9, if that were possible somehow.
For simple types (Integers etc.) an (multidimensional) Array is still one continous area of memory.
You could pass a pointer and size to your Function, and then just write that Memory with FillChar/FillByte
One System to rule them all, One Code to find them,
One IDE to bring them all, and to the Framework bind them,
in the Land of Redmond, where the Windows lie
---------------------------------------------------------------------
Code is like a joke: If you have to explain it, it's bad

#### xixixi

• New Member
• Posts: 21
##### Re: array of array of type?
« Reply #7 on: June 02, 2023, 02:28:49 pm »
Perhaps arrays aren't the best fundamental type for this particular task?

It totally is.

#### xixixi

• New Member
• Posts: 21
##### Re: array of array of type?
« Reply #8 on: June 02, 2023, 02:45:10 pm »
But you are repeating the same code for each index type, which is what I want to avoid, and what open arrays are supposedly meant to solve.
Generics?

It's looking that way. Won't save on duplicated code but at least it won't be me writing it...

Quote
Even flattening the array would help me here, i.e., the procedure getting a unidimensional array of integer of length 9, if that were possible somehow.
For simple types (Integers etc.) an (multidimensional) Array is still one continous area of memory.
You could pass a pointer and size to your Function, and then just write that Memory with FillChar/FillByte

If it isn't done automatically by the compiler, then it's not worth it. Between

Code: Pascal  [Select][+][-]
1. Clear(@arr, Ord(High(Country))*Ord(High(Animal)));

and

Code: Pascal  [Select][+][-]
1. specialize Clear<Country,Animal>(arr);

I prefer the latter, since it's shorter and keeps the structure. But the ideal solution is to be able to write

Code: Pascal  [Select][+][-]
1. Clear(arr);

for any arr of type array [T, U] of V.
« Last Edit: June 02, 2023, 02:47:39 pm by xixixi »

#### Zvoni

• Hero Member
• Posts: 1936
##### Re: array of array of type?
« Reply #9 on: June 02, 2023, 02:58:27 pm »
Code: Pascal  [Select][+][-]
1. Clear(@arr, SizeOf(arr));
No need to calculate yourself

Code: Pascal  [Select][+][-]
1. program TestArrayOfArray;
2. {\$mode OBJFPC}
3. type
4.    Country = (Congo, Kenya, Tanzania);
5.    Animal  = (lion, giraffe, zebra);
6.    Biome   = (forest, rainforest, savannah);
7.
8.    TCxA = array [Country, Animal] of integer;
9.
10. var
11.    cxa: array [Country, Animal] of integer= ((0, 1, 2), (2, 3, 4), (5, 6, 7));
12.    cxa2: TCxA = ((10, 11, 12), (13,14,15), (16,17,18));
13.    cxb: array [Biome, Animal] of integer= ((100, 101, 102), (1010, 1020, 1030), (-1, -2, -3));
14.
15.
16. procedure Clear (a:PInteger;Size:Integer);
17. begin
18.   FillChar(a^,Size,0);
19. end;
20.
21. begin
22.    Clear(@cxa,SizeOf(cxa));
23.    Clear(@cxa2,SizeOf(cxa2));
24.    Clear(@cxb,SizeOf(cxb));
25. end.
One System to rule them all, One Code to find them,
One IDE to bring them all, and to the Framework bind them,
in the Land of Redmond, where the Windows lie
---------------------------------------------------------------------
Code is like a joke: If you have to explain it, it's bad

#### jamie

• Hero Member
• Posts: 5680
##### Re: array of array of type?
« Reply #10 on: June 02, 2023, 03:24:46 pm »
Those examples are easy.

FillByte(YourArray, SizeOF(YourArray),0);

with Dynamic types it gets a little more detailed because you need to RTti or calculate the amount to clear.

All of this has been indicated already.

You could also create a "Type Helper" for a specific array of your choice.

From that, all you would need would be to simply MyArray.Clear;
etc..

You could always use "Default" on a known type of array.

« Last Edit: June 02, 2023, 03:41:45 pm by jamie »
The only true wisdom is knowing you know nothing

#### xixixi

• New Member
• Posts: 21
##### Re: array of array of type?
« Reply #11 on: June 02, 2023, 03:45:43 pm »
Code: Pascal  [Select][+][-]
1. Clear(@arr, SizeOf(arr));
No need to calculate yourself

Code: Pascal  [Select][+][-]
1. program TestArrayOfArray;
2. {\$mode OBJFPC}
3. type
4.    Country = (Congo, Kenya, Tanzania);
5.    Animal  = (lion, giraffe, zebra);
6.    Biome   = (forest, rainforest, savannah);
7.
8.    TCxA = array [Country, Animal] of integer;
9.
10. var
11.    cxa: array [Country, Animal] of integer= ((0, 1, 2), (2, 3, 4), (5, 6, 7));
12.    cxa2: TCxA = ((10, 11, 12), (13,14,15), (16,17,18));
13.    cxb: array [Biome, Animal] of integer= ((100, 101, 102), (1010, 1020, 1030), (-1, -2, -3));
14.
15.
16. procedure Clear (a:PInteger;Size:Integer);
17. begin
18.   FillChar(a^,Size,0);
19. end;
20.
21. begin
22.    Clear(@cxa,SizeOf(cxa));
23.    Clear(@cxa2,SizeOf(cxa2));
24.    Clear(@cxb,SizeOf(cxb));
25. end.

True. Since the objective is not setting it to 0 (that was just an example) the procedure would be slightly more complex, and I still lose dimension information.

While my immediate problem can be solved this way (every involved array has the same number of columns) I still would like to have a solution for the general case.

#### xixixi

• New Member
• Posts: 21
##### Re: array of array of type?
« Reply #12 on: June 02, 2023, 03:49:29 pm »
Those examples are easy.

FillByte(YourArray, SizeOF(YourArray),0);

...

I regret making the example code set all elements to 0. I should have used 1.

#### jamie

• Hero Member
• Posts: 5680
##### Re: array of array of type?
« Reply #13 on: June 02, 2023, 06:21:09 pm »
Those examples are easy.

FillByte(YourArray, SizeOF(YourArray),0);

...

I regret making the example code set all elements to 0. I should have used 1.

I bet you do!
Code: Pascal  [Select][+][-]
1.  FillDWord(A,SizeOF(A) DIV 4, 1);
2.

I think we can do this all day!

The only true wisdom is knowing you know nothing

#### xixixi

• New Member
• Posts: 21
##### Re: array of array of type?
« Reply #14 on: June 02, 2023, 06:58:43 pm »
Code: Pascal  [Select][+][-]
1.  FillDWord(A,SizeOF(A) DIV 4, 1);
2.

Really?
Code: Pascal  [Select][+][-]
1. program Size;
2.
3. var a: array [1..3, 1..3] of integer;
4.
5. begin
6.    WriteLn('FullLength(a)   = ', Length(a)*Length(a[1]));
7.    WriteLn('SizeOf(a)       = ', SizeOf(a));
8.    WriteLn('SizeOf(integer) = ', SizeOf(integer));
9.    WriteLn('SizeOf(a) div 4 = ', SizeOf(a) div 4);
10.    WriteLn('whoops!');
11. end.
12.

Code: [Select]
`FullLength(a)   = 9SizeOf(a)       = 18SizeOf(integer) = 2SizeOf(a) div 4 = 4whoops!`
I think we can do this all day!

Let's rather stop here.