Page 1 of 1

Linked list, structure and how to refer to field dynamically

Posted: Tue Nov 05, 2013 6:24 pm
by Techie42
Hi,

I would like to know if there is some way to dynamically refer to structure fields in a linked list.

I'm not sure how to word this, so I'll try and explain with a bit of code.

Code: Select all

Structure MyStructure
  top.i
  middle.i
  bottom.i
EndStructure

Global fred.s

Global NewList myList.MyStructure()

fred  = "middle"

Debug myList()\{fred}  ; this would display the value of myList()\middle
For example, I may have a list containing fifty elements. Each structure field of each element may not always need a value, depending on some other criteria. I know this sounds vague, and I cannot provide a code sample to illustrate this criteria, but it should not matter.

I would simply like to refer to a field of an element by using a variable as the field name, such as myList()\{fred} where the variable "fred" contains the string "middle".

This would be particularly useful in a loop, where the original dataset has been read from a database, and depending on the value in a given record field, only a particular list element field needs to be read. This would eliminate a lot of repetition and multiple "if" / "select" statements.

Apologies for the vagueness, but irrespective of the origin of my request, the crucial point is regarding referencing list element fields.

Thanks in advance for any assistance.

Re: Linked list, structure and how to refer to field dynamic

Posted: Tue Nov 05, 2013 7:15 pm
by idle
really not sure what you want there, What is it that you're trying to achieve?

maybe you should be using a map instead or a tree

Re: Linked list, structure and how to refer to field dynamic

Posted: Tue Nov 05, 2013 7:34 pm
by netmaestro
The answer to your question is "pretty much no", you can use a macro to reduce coding somewhat but it's not so much use for dynamic stuff. If you're willing to do a bit of work up front though, you can greatly simplify coding later by using offsets rather than names:

Code: Select all

Structure MyStructure
  top.i
  middle.i
  bottom.i
EndStructure

Global top    = OffsetOf(MyStructure\top)
Global middle = OffsetOf(MyStructure\middle)
Global bottom = OffsetOf(MyStructure\bottom)

Procedure GetField(List Listin.MyStructure(), field)
  Select field
    Case top
      result = PeekI(listin()+OffsetOf(MyStructure\top))
      
    Case middle
      result = PeekI(listin()+OffsetOf(MyStructure\middle))
      
    Case bottom
      result = PeekI(listin()+OffsetOf(MyStructure\bottom))
  EndSelect
  ProcedureReturn result
EndProcedure

Procedure SetField(List Listin.MyStructure(), field, value)
  Select field
    Case top
      PokeI(listin()+OffsetOf(MyStructure\top), value)
      
    Case middle
      PokeI(listin()+OffsetOf(MyStructure\middle), value)
      
    Case bottom
      PokeI(listin()+OffsetOf(MyStructure\bottom), value)
  EndSelect

EndProcedure

Global NewList myList.MyStructure()
AddElement(myList())

SetField(mylist(), middle, 88)

Debug GetField(mylist(), middle)

Re: Linked list, structure and how to refer to field dynamic

Posted: Tue Nov 05, 2013 8:55 pm
by Little John
It seems to me that combining both idle's and netmaestro's approaches comes pretty close to the original request. :-)

Code: Select all

EnableExplicit

Structure MyStructure
   top.i
   middle.i
   bottom.i
EndStructure

Global NewMap Offset.i()
Offset("top")    = OffsetOf(MyStructure\top)
Offset("middle") = OffsetOf(MyStructure\middle)
Offset("bottom") = OffsetOf(MyStructure\bottom)

Procedure.i GetField (List Listin.MyStructure(), field$)
   Protected result.i
   
   If FindMapElement(Offset(), field$)
      result = PeekI(listin() + Offset())
   EndIf
   ProcedureReturn result
EndProcedure

Procedure SetField (List Listin.MyStructure(), field$, value.i)
   If FindMapElement(Offset(), field$)
      PokeI(listin() + Offset(), value)
   EndIf
EndProcedure


;-- Demo
Define Fred$
NewList myList.MyStructure()

Fred$ = "middle"
AddElement(myList())
SetField(mylist(), Fred$, 88)
Debug GetField(mylist(), Fred$)

Re: Linked list, structure and how to refer to field dynamic

Posted: Tue Nov 05, 2013 10:19 pm
by Techie42
Hi everyone,

Thanks for the quick responses...I try not to ask questions too often, but when I do, I know it won't take long for those far more knowledgeable than I to respond...and I believe that's one of the reasons the PB forums are so helpful, friendly and abound with good expert advice. Thank you.

I like both code examples, and the idea of using a Map as a helper is great.

I'm very much in favour of code readability and re-use, and your solutions provide me with exactly that. I'll take on-board your suggestions and see where they lead me.

Just for info, the application I'm working on uses GDI+, FTP and MySQL to upload images (and their various attributes) to a server and update a database if the images uploaded successfully. It is complicated by the fact that there are many different image sizes pre-configured for use, so each base image is used to generate many different sized images on the local PC, then the web server is checked to see if any have already been uploaded, and just the differences are generated and uploaded (with the option of over-riding specific images). This reduces the overall load on the web-server, but means that images need to be co-ordinated in two places, both locally and remotely. Add to this the fact that new image sizes can be added to the system, and you may begin to see the reasoning behind my original question; not all image sizes may exist for each image, and new ones may be added. Also, trying to keep network requests to a minimum whilst keeping the application responsive is a fine balance, and throwing threads into the mix keeps life interesting :-)

Sorry I can't be more explicit, but the software is for a client and I have to be careful :wink:

Thanks again for the help and advice.