Creating An Array Name At Runtime?

Just starting out? Need help? Post your questions and find answers here.
staringfrog
User
User
Posts: 58
Joined: Wed Feb 27, 2013 9:36 am

Creating An Array Name At Runtime?

Post by staringfrog »

Could you tell me what are the (right/slick) ways of creating array names at runtime? I but vaguely remember there are some cute operators in languages like C or PHP that turn a variable value into a new variable's name, though of course I don't expect such syntax flexibility from PB. From what I've learned up until now, this is the only way I can do this in me PB code:

Code: Select all

Macro NewDim(counter,size)
Dim MSV#counter.s(size)
MSV#counter(size)="Result"
Debug MSV#counter(size)
EndMacro
foo.i=0 : bar.i=0
NewDim(foo,bar)
Is this the only option for creating an unlimited/non-predefined number of arrays in PB? Or should I use some different logic instead?
Coding's men's knitwork.
User avatar
Demivec
Addict
Addict
Posts: 4283
Joined: Mon Jul 25, 2005 3:51 pm
Location: Utah, USA

Re: Creating An Array Name At Runtime?

Post by Demivec »

You cannot define a variable's name at runtime. The variable's name is only used at compile-time to produce the compiled code. There are some exceptions to this using the 'RunTime' keyword (the keyword exposes selected compile-time names to access via strings at runtime).

In addition to the method you showed for creating compile-time names here is a method for creating runtime names using a map:

Code: Select all

Structure MSV_Array
  Array MSV.s(0)
EndStructure

NewMap MSV_Array.MSV_Array()

Procedure NewDim(counter, size)
  Shared MSV_Array()
  AddMapElement(MSV_Array(), "MSV" + Str(counter))
  Dim MSV_Array()\MSV(size)
  MSV_Array()\MSV(size)="Result"
  Debug MSV_Array()\MSV(size)
EndProcedure

foo.i = 0: bar.i = 0
NewDim(foo, bar)
foo = 2: bar = 10
NewDim(foo, bar)

Debug "0 " + MSV_Array("MSV0")\MSV(0)
Debug "2 " + MSV_Array("MSV2")\MSV(10)

Debug "5 " + MSV_Array("MSV5")\MSV(0) ;doesn't exist (reference uses default declared size)
Debug "3 " + MSV_Array("MSV3")\MSV(0) 
Debug "95 " + MSV_Array("MSV95")\MSV(0)
The map allows for flexible naming at runtime and reference of the array when combined with the structure that houses the array itself.
staringfrog
User
User
Posts: 58
Joined: Wed Feb 27, 2013 9:36 am

Re: Creating An Array Name At Runtime?

Post by staringfrog »

Thank you, Demivec, for your full explanation,

yes, I didn't think of maps as accepting concatenated array names for keys. All in all, your modification provides much more readable and flexible albeit a bit more complicated (on the face of it) solution, as well as exemplifies that basic principle behind PureBasic data manipulation (that I agree with) which states — if you want to do something really subtle with PB arrays, use arrays together with maps, and with linked-lists, and with structures. Not to mention pointers :wink:
Coding's men's knitwork.
User avatar
Demivec
Addict
Addict
Posts: 4283
Joined: Mon Jul 25, 2005 3:51 pm
Location: Utah, USA

Re: Creating An Array Name At Runtime?

Post by Demivec »

Your welcome. :wink:
All in all, your modification provides much more readable and flexible albeit a bit more complicated (on the face of it) solution, as well as exemplifies that basic principle behind PureBasic data manipulation (that I agree with) which states — if you want to do something really subtle with PB arrays, use arrays together with maps, and with linked-lists, and with structures. Not to mention pointers :wink:
The key to it all is really the structure containing the array. Here is a slightly less complicated version using arrays of arrays. It only uses an index# instead of a custom name and would be a little simply and faster because a hash of the array's name wouldn't have to be made (for lookup in a map). It also allows the side benefit of being able to access more than one of the arrays at the same time (although this could be done with the former map example using pointers).

Code: Select all

Structure MSV_Array
  Array MSV.s(0)
EndStructure

Dim MSV_Arr.MSV_Array(0)

Procedure NewDim(counter, size)
  Shared MSV_Arr()
  If ArraySize(MSV_Arr()) < counter
    ReDim MSV_Arr.MSV_Array(counter)
  EndIf
  
  Dim MSV_Arr(counter)\MSV(size)
  MSV_Arr(counter)\MSV(size)="Result"
  Debug MSV_Arr(counter)\MSV(size)
EndProcedure

foo.i = 0: bar.i = 0
NewDim(foo, bar)
NewDim(2, 10)

Debug "0 " + MSV_Arr(0)\MSV(0)
Debug "2 " + MSV_Arr(2)\MSV(10) ;this will also create a default size for an array at index 1

Debug "1 " + MSV_Arr(1)\MSV(0) ;not formally declared and it's base element is still empty
Post Reply