### Bookstore

 Computer Math and Games in Pascal (preview) Lazarus Handbook

### Author Topic: How to go through all the elements of a record  (Read 717 times)

#### cpalx

• Hero Member
• Posts: 634
##### How to go through all the elements of a record
« on: April 08, 2020, 12:57:09 am »
Hello,

does some body knows how to go through all the elements of a record?

#### winni

• Hero Member
• Posts: 1347
##### Re: How to go through all the elements of a record
« Reply #1 on: April 08, 2020, 01:23:51 am »
Hi!

No - but ....

* In case  all your record items got the same size you can define a variant record with the part you needed and an array[..] of sometype and then you  can loop through the array.

*The other solution is the extended for .. in syntax where you can assign an enumerator to "anything".

The page is here:  https://wiki.freepascal.org/for-in_loop

Look for  "Declaring enumerators".

Winni
« Last Edit: April 08, 2020, 01:29:28 am by winni »

#### jamie

• Hero Member
• Posts: 2916
##### Re: How to go through all the elements of a record
« Reply #2 on: April 08, 2020, 02:00:39 am »
can you please give us an example of what you are referring to ?

This leads my mind to many different scenarios.
Number 1 at blue screen app creations!

#### cpalx

• Hero Member
• Posts: 634
##### Re: How to go through all the elements of a record
« Reply #3 on: April 08, 2020, 04:12:48 pm »
Type
Code: Pascal  [Select][+][-]
1.  TMyRecord = Record
2.      Field1
3.      Field2: Integer;
4.      Field3: string;
5.  end;
6.
7. var MyRecord: TMyREcord

i need something like

for min(MyRecord) to max(MyRecord) do
ang get all ellements (Field1,2,3)

#### marcio2003

• New Member
• Posts: 29
##### Re: How to go through all the elements of a record
« Reply #4 on: April 08, 2020, 04:38:57 pm »
The data you want read is stored in hard disk?

#### ASerge

• Hero Member
• Posts: 1559
##### Re: How to go through all the elements of a record
« Reply #5 on: April 08, 2020, 04:54:31 pm »
for min(MyRecord) to max(MyRecord) do
ang get all ellements (Field1,2,3)
Code: Pascal  [Select][+][-]
1. {\$APPTYPE CONSOLE}
2. {\$MODE OBJFPC}
3. {\$LONGSTRINGS ON}
4.
5. uses TypInfo;
6.
7. procedure EnumFields(RecInfo: PTypeInfo);
8. var
9.   Data: PTypeData;
10.   i: Integer;
11.   MF: PManagedField;
12. begin
13.   if not Assigned(RecInfo) or (RecInfo^.Kind <> tkRecord) then
14.     Exit;
15.   Writeln('Record type=', RecInfo^.Name);
16.   Data := GetTypeData(RecInfo);
17.   MF := Pointer(PByte(@Data^.ManagedFldCount) + SizeOf(Data^.ManagedFldCount));
18.   for i := 1 to Data^.ManagedFldCount do
19.   begin
20.     Writeln('Type=', MF^.TypeRef^.Name, ', offset=', MF^.FldOffset);
21.     Inc(MF);
22.   end;
23. end;
24.
25. type
26.   TMyRecord = record
27.     Field1: Double;
28.     Field2: Integer;
29.     Field3: string;
30.   end;
31.
32. begin
33.   EnumFields(TypeInfo(TMyRecord));
35. end.

#### jamie

• Hero Member
• Posts: 2916
##### Re: How to go through all the elements of a record
« Reply #6 on: April 08, 2020, 06:11:24 pm »
wouldn't it be better to use Advanced Records and write an enumerator for it along with maybe a items array that returns type?

I don't know, what you are showing there looks like lard generation.

I hope the compiler does not store type info for every record type in the system in my EXE file!

Number 1 at blue screen app creations!

#### jamie

• Hero Member
• Posts: 2916
##### Re: How to go through all the elements of a record
« Reply #7 on: April 08, 2020, 06:31:20 pm »
Code: Pascal  [Select][+][-]
1. Type TMyRecord = Record
2.       Field1:Byte;
3.       Field2:Integer;
4.       Field3:String;
5.       Function GetElement(Index:Integer):variant;
6.    End;
7.
8.  implementation
9.
10. {\$R *.lfm}
11. Function TMyRecord.GetElement(index:Integer):variant;
12. Begin
13.   Case Index of
14.    1:result := Self.Field1;
15.    2:result := self.Field2;
16.    3:Result := self.Field3;
17.   end;
18. end;
19. procedure TForm1.Button7Click(Sender: TObject);
20. var
21.   R:TMyRecord;
22.
23. begin
24.   R.Field1 := 10;
25.   R.Field3 := 'test';
26.   Caption := R.GetElement(1);
27.   Caption := Caption + R.GetElement(3);
28. end;
29.
30.
31.
Number 1 at blue screen app creations!

#### ASerge

• Hero Member
• Posts: 1559
##### Re: How to go through all the elements of a record
« Reply #8 on: April 08, 2020, 07:28:12 pm »
Code: Pascal  [Select][+][-]
1. Function TMyRecord.GetElement(index:Integer):variant;
2. Begin
3.   Case Index of
4.    1:result := Self.Field1;
5.    2:result := self.Field2;
6.    3:Result := self.Field3;
7.   end;
8. end;
This solution is only for one specific type. I specifically wrote the procedure in the example earlier than the type it handles.
The compiler inserts type data into the code only when it sees the TypeInfo function, which is what the help hints at TypeInfo.

#### jamie

• Hero Member
• Posts: 2916
##### Re: How to go through all the elements of a record
« Reply #9 on: April 08, 2020, 07:44:58 pm »
Code: Pascal  [Select][+][-]
1. Function TMyRecord.GetElement(index:Integer):variant;
2. Begin
3.   Case Index of
4.    1:result := Self.Field1;
5.    2:result := self.Field2;
6.    3:Result := self.Field3;
7.   end;
8. end;
This solution is only for one specific type. I specifically wrote the procedure in the example earlier than the type it handles.
The compiler inserts type data into the code only when it sees the TypeInfo function, which is what the help hints at <<<< Good To knowTypeInfo.

Thanks for the info.
Number 1 at blue screen app creations!

#### PascalDragon

• Hero Member
• Posts: 1497
• Compiler Developer
##### Re: How to go through all the elements of a record
« Reply #10 on: April 09, 2020, 01:30:43 pm »
I hope the compiler does not store type info for every record type in the system in my EXE file!

Yes, it does. Also for classes, method and procedure pointers and basically any type. But only those that are used in your program.

#### marcov

• Global Moderator
• Hero Member
• Posts: 8381
• FPC developer.
##### Re: How to go through all the elements of a record
« Reply #11 on: April 09, 2020, 02:26:55 pm »
I hope the compiler does not store type info for every record type in the system in my EXE file!

Yes, it does. Also for classes, method and procedure pointers and basically any type. But only those that are used in your program.

Does it honor {\$RTTI EXPLICIT METHODS([]) PROPERTIES([]) FIELDS([])}   ?

#### kupferstecher

• Sr. Member
• Posts: 388
##### Re: How to go through all the elements of a record
« Reply #12 on: April 09, 2020, 03:36:57 pm »
Yes, it does. Also for classes, method and procedure pointers and basically any type. But only those that are used in your program.
Only those type infos or only those types (that are used in your program)?

#### PascalDragon

• Hero Member
• Posts: 1497
• Compiler Developer
##### Re: How to go through all the elements of a record
« Reply #13 on: April 09, 2020, 04:25:25 pm »
I hope the compiler does not store type info for every record type in the system in my EXE file!

Yes, it does. Also for classes, method and procedure pointers and basically any type. But only those that are used in your program.

Does it honor {\$RTTI EXPLICIT METHODS([]) PROPERTIES([]) FIELDS([])}   ?

As you should know we do not have extended RTTI, so this can't be answered at the current state.

Also in Delphi the information about published properties, fields and methods would still be available in the legacy parts of the RTTI even if the above directive is given.

Yes, it does. Also for classes, method and procedure pointers and basically any type. But only those that are used in your program.
Only those type infos or only those types (that are used in your program)?

Types themselves do not exist in the final binary (it's only assembly code after all). Their type information does however (if the corresponding type is used).

#### nanobit

• Jr. Member
• Posts: 59
##### Re: How to go through all the elements of a record
« Reply #14 on: April 09, 2020, 04:33:21 pm »
Types themselves do not exist in the final binary (it's only assembly code after all). Their type information does however (if the corresponding type is used).

Is there a way to hide the used typenames in the binaries?
Even something simple would help like xor or reverse string, with custom write/readName function.