Can you access structure fields by index?

Just starting out? Need help? Post your questions and find answers here.
RobertSF
User
User
Posts: 61
Joined: Thu May 03, 2018 4:24 pm

Can you access structure fields by index?

Post by RobertSF »

If you have

Code: Select all

Structure RecordStructure
  ID.l
  Name.s
  Age.l
  Country.s
  Email.s
EndStructure
Define Record.RecordStructure
is there a way of accessing the elements by index? That is, instead of Record\Age, it would be Record\2 (assuming zero-based index). I'm thinking it can be done with pointers, SizeOf and OffsetOf, but I don't know how, and my experimenting has gone nowhere. I'm trying to generalize a routine so that it can process lists with different types of structures.
wilbert
PureBasic Expert
PureBasic Expert
Posts: 3870
Joined: Sun Aug 08, 2004 5:21 am
Location: Netherlands

Re: Can you access structure fields by index?

Post by wilbert »

If you would only use integer and string types, you could do something like

Code: Select all

Structure RecordStructure
  ; Indexed fields with length 0
  IntField.i[0]
  StrField.s[0]
  ; Record fields
  ID.i
  Name.s
  Age.i
  Country.s
  Email.s
EndStructure

Define Record.RecordStructure

Record\Name = "John"
Record\Age = 25
Record\Country = "France"

Debug Record\Name
Debug Record\StrField[1]

Debug Record\Age
Debug Record\IntField[2]

Debug Record\Country
Debug Record\StrField[3]
Windows (x64)
Raspberry Pi OS (Arm64)
#NULL
Addict
Addict
Posts: 1440
Joined: Thu Aug 30, 2007 11:54 pm
Location: right here

Re: Can you access structure fields by index?

Post by #NULL »

I don't think you could ever use a dynamic value like a variable for the field index, so if you have to hard-code \1 anyway you could as well just hardcode \Name, but some ideas:

with a proxy structure

Code: Select all

Structure RecordStructure
  ID.l
  Name.s
EndStructure

Structure RecordStructureN
  _0.l
  _1.s
EndStructure

*rsn.RecordStructureN = @rs.RecordStructure
*rsn\_0 = 123
*rsn\_1 = "abc"
Debug rs\ID
Debug rs\Name
or with structureUnion

Code: Select all

Structure RecordStructure
  StructureUnion
    _0.l
    ID.l
  EndStructureUnion
  StructureUnion
    _1.s
    Name.s
  EndStructureUnion
EndStructure

Define Record.RecordStructure

Record\_0 = 123
Debug Record\_0
Record\_1 = "abc"
Debug Record\_1
hiding the underscore with a macro

Code: Select all

Structure RecordStructure
  StructureUnion
    _0.l
    ID.l
  EndStructureUnion
  StructureUnion
    _1.s
    Name.s
  EndStructureUnion
EndStructure

Define Record.RecordStructure

Record\_0 = 123
Debug Record\_0
Record\_1 = "abc"
Debug Record\_1

Macro byIndex(i)
  _#i
EndMacro

Record\byIndex(0) + 1
Record\byIndex(1) + "d"
Debug Record\ID
Debug Record\Name
Are you sure you know what you want to do? Because you have to treat integer and string fields for example differently anyway so just an index would cut it.
User avatar
RSBasic
Moderator
Moderator
Posts: 1218
Joined: Thu Dec 31, 2009 11:05 pm
Location: Gernsbach (Germany)
Contact:

Re: Can you access structure fields by index?

Post by RSBasic »

If I want to access it via an index, I use NewMap:

Code: Select all

EnableExplicit

Structure RecordStructure
  Name.s
  Age.l
  Country.s
  Email.s
EndStructure

Define NewMap RecordStructure.RecordStructure()

RecordStructure("1")\Age = 29
Image
Image
#NULL
Addict
Addict
Posts: 1440
Joined: Thu Aug 30, 2007 11:54 pm
Location: right here

Re: Can you access structure fields by index?

Post by #NULL »

He wants to index the fields in a record, not a record in a collection. :)

If you use Align with the Structure with a large enough value you can probably Peek/Poke at offsets multiplied with the index.
RobertSF
User
User
Posts: 61
Joined: Thu May 03, 2018 4:24 pm

Re: Can you access structure fields by index?

Post by RobertSF »

Ok, thanks for the ideas everyone. I'll try them. I guess the sticking point is this: "I don't think you could ever use a dynamic value like a variable for the field index."
User avatar
idle
Always Here
Always Here
Posts: 5042
Joined: Fri Sep 21, 2007 5:52 am
Location: New Zealand

Re: Can you access structure fields by index?

Post by idle »

If you're wanting to write a generic routine to process arbitrary structures in a list, that's way to hard at the moment.
Currently you can't get the type information you need at runtime. TypeOf and OffsetOf are compiler functions
so they're of little use.

If you want a generic routine to process know structures in your program you could try this.

Code: Select all

#RECSTRUCTA = 1
#RECSTRUCTB = 2 

Structure RecordStructureA
  ID.l
  Name.s
  Age.l
  Country.s
  Email.s
EndStructure

Structure RecordStructureB
  ID.l
  Height.i
  Weight.l
  HairColor.s
EndStructure

Structure records 
  type.b 
  StructureUnion 
    *recA.RecordStructureA 
    *recB.RecordStructureB 
  EndStructureUnion 
EndStructure   


Procedure AddElementRecords(List rec.records(),type) 
  AddElement(rec()) 
  rec()\type = type 
  Select type 
    Case #RECSTRUCTA   
      rec()\recA = AllocateStructure(RecordStructureA) 
    Case #RECSTRUCTB 
      rec()\recB = AllocateStructure(RecordStructureB)
  EndSelect 
EndProcedure   

Procedure FreeListRecords(List rec.records())
  ForEach rec()
    Select type 
    Case #RECSTRUCTA   
      FreeStructure(rec()\recA) 
    Case #RECSTRUCTB 
      FreeStructure(rec()\recB)
   EndSelect    
  Next   
  FreeList(Rec()) 
EndProcedure   

Procedure process(List record.records()) 
    
  ForEach record() 
    Select record()\type 
    Case #RECSTRUCTA 
      Debug record()\recA\Age 
      Debug record()\recA\Country 
      Debug record()\recA\Name 
    Case #RECSTRUCTB
      Debug Record()\recB\HairColor 
      Debug record()\recB\Height 
      Debug record()\recB\Weight 
  EndSelect
  Next 
EndProcedure   

Global NewList records.Records()  

AddElementRecords(records(),#RECSTRUCTA) 

Records()\recA\Age = 50 
Records()\recA\Country = "NZ"
Records()\recA\Name = "idle" 

AddElementRecords(records(),#RECSTRUCTB) 

records()\recB\HairColor = "Blond"
records()\recB\Height = 186 
records()\recB\Weight = 85 

process(records())  

Windows 11, Manjaro, Raspberry Pi OS
Image
Post Reply