Recent

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

cpalx

  • Hero Member
  • *****
  • Posts: 753
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: 3197
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: 6077
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.
The only true wisdom is knowing you know nothing

cpalx

  • Hero Member
  • *****
  • Posts: 753
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

  • Jr. Member
  • **
  • Posts: 69
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?
Lazarus 2.0.10 Windows 10 64bits

ASerge

  • Hero Member
  • *****
  • Posts: 2212
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));
  34.   Readln;
  35. end.

jamie

  • Hero Member
  • *****
  • Posts: 6077
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!

The only true wisdom is knowing you know nothing

jamie

  • Hero Member
  • *****
  • Posts: 6077
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.  
The only true wisdom is knowing you know nothing

ASerge

  • Hero Member
  • *****
  • Posts: 2212
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: 6077
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.
The only true wisdom is knowing you know nothing

PascalDragon

  • Hero Member
  • *****
  • Posts: 5444
  • 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

  • Administrator
  • Hero Member
  • *
  • Posts: 11351
  • 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

  • Hero Member
  • *****
  • Posts: 583
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: 5444
  • 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

  • Full Member
  • ***
  • Posts: 154
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.

 

TinyPortal © 2005-2018