Recent

Author Topic: array of array of type?  (Read 1993 times)

xixixi

  • New Member
  • *
  • Posts: 25
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 "TI
ntArrArr"                                                                                                                         
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 "TInt
ArrArr"

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: 6133
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.  
  77.    ReadLn;
  78. end.

xixixi

  • New Member
  • *
  • Posts: 25
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: 25
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: 10
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: 2327
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: 25
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: 25
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: 2327
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: 6133
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. :o

 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..

Wanted to add:

   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: 25
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: 25
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: 6133
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!
 :D
The only true wisdom is knowing you know nothing

xixixi

  • New Member
  • *
  • Posts: 25
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)   = 9
SizeOf(a)       = 18
SizeOf(integer) = 2
SizeOf(a) div 4 = 4
whoops!

I think we can do this all day!
 :D

Let's rather stop here.

 

TinyPortal © 2005-2018