Bookstore

 Computer Math and Games in Pascal (preview) Lazarus Handbook

Author Topic: Array of range and enum  (Read 715 times)

Okoba

• Sr. Member
• Posts: 478
Array of range and enum
« on: September 24, 2023, 05:15:17 pm »
I want to make an array of all possible values of enum and range type, in an easy way, without loops. Something like the sample. Is there a way, as the sample does not work.
Code: Pascal  [Select][+][-]
1. program Project1;
2.
3. type
4.   TEnum = (A, B, C, D);
5.   TRange = 1..10;
6.
7. var
8.   EnumArray:array of TEnum=(Low(TEnum)..High(TEnum));
9.   RangeArray:array of TRange=(Low(TRange)..High(TRange));
10. begin
11. end.

Fibonacci

• Full Member
• Posts: 219
• #PDK
Re: Array of range and enum
« Reply #1 on: September 24, 2023, 05:30:48 pm »
Code: Pascal  [Select][+][-]
1. type
2.   TEnum = (A, B, C, D);
3.   TRange = 1..10;
4.
5. var
6.   //EnumArray:array of TEnum=(Low(TEnum)..High(TEnum));
7.   EnumArray:array[low(TEnum)..high(TEnum)] of Integer;
8.   //RangeArray:array of TRange=(Low(TRange)..High(TRange));
9.   RangeArray:array[low(TRange)..high(TRange)] of Integer;
10.
11.   i: integer;
12. begin
13.   for i := integer(low(EnumArray)) to integer(high(EnumArray)) do begin
14.     writeln('EnumArray[', i, '] = ', TEnum(i));
15.   end;
16.
17.   writeln;
18.
19.   for i := low(RangeArray) to high(RangeArray) do begin
20.     writeln('RangeArray[', i, '] = ', i);
21.   end;
22.
24. end.

Code: [Select]
EnumArray[0] = A
EnumArray[1] = B
EnumArray[2] = C
EnumArray[3] = D

RangeArray[1] = 1
RangeArray[2] = 2
RangeArray[3] = 3
RangeArray[4] = 4
RangeArray[5] = 5
RangeArray[6] = 6
RangeArray[7] = 7
RangeArray[8] = 8
RangeArray[9] = 9
RangeArray[10] = 10

But if you set enum type to: TEnum = (A, B, C=30, D)
Then you will have a problem
« Last Edit: September 24, 2023, 05:34:42 pm by Fibonacci »

Okoba

• Sr. Member
• Posts: 478
Re: Array of range and enum
« Reply #2 on: September 24, 2023, 05:37:52 pm »
That is an interesting hack. Thank you.

jamie

• Hero Member
• Posts: 5835
Re: Array of range and enum
« Reply #3 on: September 24, 2023, 05:45:48 pm »
Code: Pascal  [Select][+][-]
1.   A:Array[TRange]of Integer;
2.   B:Array[TENum] of integer;
3.

The only true wisdom is knowing you know nothing

Okoba

• Sr. Member
• Posts: 478
Re: Array of range and enum
« Reply #4 on: September 24, 2023, 05:47:27 pm »
Yes it is more clear. Although I wished there was no need for a hack like this, still better than using a loop!

Kays

• Hero Member
• Posts: 546
• Whasup!?
Re: Array of range and enum
« Reply #5 on: September 24, 2023, 05:48:06 pm »
May I remind you, as it stands Okoba wants:
Code: Pascal  [Select][+][-]
1.         type
2.                 enumeration = (A, B, C, D);
3.         var
4.                 field: array of enumeration;
5.         begin
6.                 field := [A, B, C, D];
7.                 { which is shorthand for }
8.                 setLength(field, 4);
9.                 field[0] := A;
10.                 field[1] := B;
11.                 field[2] := C;
12.                 field[3] := D;
13.         end.
But without writing it out or populating said array with a for-loop.
Yours Sincerely
Kai Burghardt

jamie

• Hero Member
• Posts: 5835
Re: Array of range and enum
« Reply #6 on: September 24, 2023, 05:58:08 pm »
You mean this in the VAr section?

Code: Pascal  [Select][+][-]
1.   Z:Array[0..3]of TEnum =(A,B,C,D);
2.
3.
or
Code: Pascal  [Select][+][-]
1.   Z:Array[TRange]of TEnum =(A,B,C,D);
2.
« Last Edit: September 24, 2023, 05:59:46 pm by jamie »
The only true wisdom is knowing you know nothing

PascalDragon

• Hero Member
• Posts: 5281
• Compiler Developer
Re: Array of range and enum
« Reply #7 on: September 24, 2023, 10:09:29 pm »
Yes it is more clear. Although I wished there was no need for a hack like this, still better than using a loop!

This is not a hack. The index of a static array is either a range or an ordinal type.

I want to make an array of all possible values of enum and range type, in an easy way, without loops. Something like the sample. Is there a way, as the sample does not work.
Code: Pascal  [Select][+][-]
1. program Project1;
2.
3. type
4.   TEnum = (A, B, C, D);
5.   TRange = 1..10;
6.
7. var
8.   EnumArray:array of TEnum=(Low(TEnum)..High(TEnum));
9.   RangeArray:array of TRange=(Low(TRange)..High(TRange));
10. begin
11. end.

No, there is no way to do this at compile time except you write out all values as jamie showed. However you can create a generic function that does what you want, this way you only need to write this out only once:

Code: Pascal  [Select][+][-]
1. program range;
2.
3. {\$mode objfpc}
4.
5. type
6.   TEnum = (A, B, C, D);
7.   TRange = 1..10;
8.
9. generic function GenerateRangeArray<T>: specialize TArray<T>;
10. var
11.   i: SizeInt;
12. begin
13.   SetLength(Result, Ord(High(T)) - Ord(Low(T)) + 1);
14.   for i := 0 to High(Result) do
15.     Result[i] := T(Ord(Low(T)) + i);
16. end;
17.
18. var
19.   EnumArray:array of TEnum;
20.   RangeArray:array of TRange;
21. begin
22.   EnumArray := specialize GenerateRangeArray<TEnum>;
23.   RangeArray := specialize GenerateRangeArray<TRange>;
24. end.

Okoba

• Sr. Member
• Posts: 478
Re: Array of range and enum
« Reply #8 on: September 25, 2023, 05:30:18 pm »
@PascalDragon I meant hack as the array key is the value, and not the array value. You got what I need with your sample code and that is what I want. Your way is cool too, although I wished for a way to define these ranges const or var just like as we define the TRange type how you can call open array parameter
Code: Pascal  [Select][+][-]
1. program Project1;
2.
3.   procedure Test(A: array of Integer);
4.   var
5.     I: Integer;
6.   begin
7.     for I := Low(A) to High(A) do
8.       WriteLn(A[I]);
9.   end;
10.
11. const
12.   A: array of Integer = (1, 2, 3, 4);
13. begin
14.   Test(A[Low(A)..High(A)]);
15.   Test(A[Low(A) + 1..High(A)]);