This question is hard to explain

LiveCode is the premier environment for creating multi-platform solutions for all major operating systems - Windows, Mac OS X, Linux, the Web, Server environments and Mobile platforms. Brand new to LiveCode? Welcome!

Moderators: FourthWorld, heatherlaine, Klaus, kevinmiller, robinmiller

Post Reply
magice
Posts: 457
Joined: Wed Mar 18, 2009 12:57 am

This question is hard to explain

Post by magice » Sun Apr 12, 2009 3:18 am

ok I have a program i am working on in which the end user will be creating arrays. Each time they make a new one the name will be incremented.
e.g. tMainArray1, tMainArray2, tMainArray3 etc. The problem I am having, is in declaring them global. I could create a long list of globals and hope the end user doesn't end up creating more then i planned for, but that is messy. so, what I have been playing with is this:

Code: Select all

global tMainArrayInc
repeat with x = 1 to the value of tMainArrayInc
      do "global tMainArray" &  the value of x
   end repeat
(tMainArrayInc is the variable i use to increment the array names) Obviously this isn't working or i wouldn't be posting. I hope though that it is enough to explain what I am trying to do. What can I do that will work?

sturgis
Livecode Opensource Backer
Livecode Opensource Backer
Posts: 1685
Joined: Sat Feb 28, 2009 11:49 pm

Re: This question is hard to explain

Post by sturgis » Sun Apr 12, 2009 4:34 am

You might consider doing this as a multi-dimentional array. Without knowing exactly what you'll be wanting to do, hard to tell you exactly how to set it up, but as an example you can do something like this.

Code: Select all

global theArray
on mouseUp
   repeat with x = 1 to 20
      put "test: " & x into theArray["tMainArray" & x][1]
      put "test2: " & x after theArray["tMainArray" &  x][2]
   end repeat
end mouseUp
I have this in a button, on clicking it the single array variable is declared, then tMainArray# (varying number based on x) is used as a key, with subkeys 1 and 2 used for test data.
Click the button, then you can either test with another button or go to message box and try something like this.

Code: Select all

put theArray["tMainArray1"][1]
 
Which will put out 'test: 1'. If you change it to theArray["tMainArray1"][2] the out put will be 'test2: 1' Same for all 20 tMainArrays.. tMainArray20[1] will put out 'test: 20' [2] will put out 'test2: 20'

Will this do what you need?
magice wrote:ok I have a program i am working on in which the end user will be creating arrays. Each time they make a new one the name will be incremented.
e.g. tMainArray1, tMainArray2, tMainArray3 etc. The problem I am having, is in declaring them global. I could create a long list of globals and hope the end user doesn't end up creating more then i planned for, but that is messy. so, what I have been playing with is this:

Code: Select all

global tMainArrayInc
repeat with x = 1 to the value of tMainArrayInc
      do "global tMainArray" &  the value of x
   end repeat
(tMainArrayInc is the variable i use to increment the array names) Obviously this isn't working or i wouldn't be posting. I hope though that it is enough to explain what I am trying to do. What can I do that will work?
Edit: Been pondering this a little more. If you need to add more keys to the main array at a later date, you can use 'the number of keys in.. ' to tell you how many are there already, so that you know where to continue your numbering sequence. In addition, while named keys are cool for lots of things, in this case it sounds like you probably won't need them. This will make it easier, you won't have to go through the tMainArray & x rigamarole, and can get the number of keys and increment it by 1 to expand your array.

magice
Posts: 457
Joined: Wed Mar 18, 2009 12:57 am

Post by magice » Sun Apr 12, 2009 4:53 am

Actually, that in no help. Each of the arrays are already multidimensional. Essentially what I am doing is creating an array that can be used to generate an html document with and image map using repeat loops. Each array represents all the data for one document. The elements are incremented for the number of image map areas to create within the document, and their child elements hold the data for each image map area. The final output will be several linked html documents. So' unfortunately the only way I can see to do it is to create a separate array for each document. I can declare each of them as global upon creation, but I am having trouble with recalling them later in another script. That is where my failing repeat loop comes in.....unless. Can you have a grandchild element? something like tMainArray[1][1][data]?

sturgis
Livecode Opensource Backer
Livecode Opensource Backer
Posts: 1685
Joined: Sat Feb 28, 2009 11:49 pm

Post by sturgis » Sun Apr 12, 2009 5:28 am

If i'm understanding what you mean, I think this might still be the way to go.

Setup your main array to hold all the sub information say, theArray
Insert a key for each page
theArray["firstPage"]
You said, the elements are incremented for the number of image map areas, so theArray["firstPage"] could contain sub keys 1,2,3,4,5 etc for the number of image map areas. This way you could end up with something like

Code: Select all

put "This is the data for the first image map area of my first page" into theArray["firstPage"][1]
If you had 5 image map areas for page firstPage you'd just put the data for each area into theArray["firstPage"][x] where x = 1 to 5. Need to add another page? Same exact thing.
theArray["secondPage"][1] would store the image map data for the first image map area of page 2.

Doing it similarly to your method before, could name the page keys as page# (page1 page2..)

To insert a page later, you can

Code: Select all

get the number of lines in the keys of theArray
Increment it by 1, and insert your new page key.

The nice thing about the multidimentional arrays is you can also create arrays like
theArray["page1"]["maps"][1]
theArray["page1"]["header"]
theArray["page1"["CSS"]

If you want to have changeable headers for a single page, break it down further with [1] being the first header etc. Can store different css code.. well all kinds of things.

Having said all this, I think there is another option. You could store all this information in list fields or tables on a background card.

At that point you can have a single global variable declared, and load it from the table with the needed information. Or just ignore declaring globals and grab what you need from your hidden list boxes.
magice wrote:Actually, that in no help. Each of the arrays are already multidimensional. Essentially what I am doing is creating an array that can be used to generate an html document with and image map using repeat loops. Each array represents all the data for one document. The elements are incremented for the number of image map areas to create within the document, and their child elements hold the data for each image map area. The final output will be several linked html documents. So' unfortunately the only way I can see to do it is to create a separate array for each document. I can declare each of them as global upon creation, but I am having trouble with recalling them later in another script. That is where my failing repeat loop comes in.

magice
Posts: 457
Joined: Wed Mar 18, 2009 12:57 am

Post by magice » Sun Apr 12, 2009 6:28 am

Ok I got it now. I didn't realize that you could take the child elements farther then 2 deep. :oops: Going to the level of a "Grandchild" element solves the problem nicely even if it does mean going through about 1000 lines of parsed code and adding an extra set of brackets with every reference to an array element. Thank you for the lesson in arrays.

sturgis
Livecode Opensource Backer
Livecode Opensource Backer
Posts: 1685
Joined: Sat Feb 28, 2009 11:49 pm

Re: This question is hard to explain

Post by sturgis » Sun Apr 12, 2009 7:30 am

Try something like the code below. It seems like your code should work, but I can't make it go either. This version works however. The multi array has some good things goin for it, but so does this.

This is button code, and does indeed show the names of the newly made globals in the messagebox.

Good luck!

Code: Select all

on mouseUp
   global tMainArrayInc 
   put 10 into tMainArrayInc -- don't have your tMainArrayInc so setting a val
   repeat with x = 1 to the value of tMainArrayInc
      put "tMainArray" & x into arrayName
      do "global " & arrayName
      do "put x into " & arrayName -- Just pops something into the variables. 
   end repeat
   put the globalNames
end mouseUp
I have a question regarding this for any of the gurus out there. There is a limit to how much code can be created by code in a standalone correct? Is the creation of a global subject to those limits? How would the limits apply here, if at all?

edit: Nevermind, think I answered my own question. The number of statements in the "do" command is less than 10, so this code should be fine if I understand the the scriptLimits entry.
magice wrote:ok I have a program i am working on in which the end user will be creating arrays. Each time they make a new one the name will be incremented.
e.g. tMainArray1, tMainArray2, tMainArray3 etc. The problem I am having, is in declaring them global. I could create a long list of globals and hope the end user doesn't end up creating more then i planned for, but that is messy. so, what I have been playing with is this:

Code: Select all

global tMainArrayInc
repeat with x = 1 to the value of tMainArrayInc
      do "global tMainArray" &  the value of x
   end repeat
(tMainArrayInc is the variable i use to increment the array names) Obviously this isn't working or i wouldn't be posting. I hope though that it is enough to explain what I am trying to do. What can I do that will work?

FourthWorld
VIP Livecode Opensource Backer
VIP Livecode Opensource Backer
Posts: 10049
Joined: Sat Apr 08, 2006 7:05 am
Contact:

Post by FourthWorld » Sun Apr 12, 2009 8:18 pm

sturgis, you're correct on "do": as long as the number of executable lines is 10 or fewer it'll work well.

But in general, "do" is best left as a last resort when no other method of getting what you need is available.

For storing values in globals, using a single nested array will let you store any number of values in discrete slots much more efficiently than using "do".

The "do" and "send" commands have to run through additional interpretation layers before they're executed, while most other statements are compiled when the message path loads.

Given the additional overhead, it'll almost always be the case that "do" will run slower than alternatives. It's still pretty fast, but every clock cycle saved can go into a more powerful feature later on, so I'm a big fan of trimming runtime overhead whenever practical.
Richard Gaskin
LiveCode development, training, and consulting services: Fourth World Systems
LiveCode Group on Facebook
LiveCode Group on LinkedIn

sturgis
Livecode Opensource Backer
Livecode Opensource Backer
Posts: 1685
Joined: Sat Feb 28, 2009 11:49 pm

Post by sturgis » Sun Apr 12, 2009 9:23 pm

Cool, ty much for the confirmation, appreciate it.
FourthWorld wrote:sturgis, you're correct on "do": as long as the number of executable lines is 10 or fewer it'll work well.

But in general, "do" is best left as a last resort when no other method of getting what you need is available.

For storing values in globals, using a single nested array will let you store any number of values in discrete slots much more efficiently than using "do".

The "do" and "send" commands have to run through additional interpretation layers before they're executed, while most other statements are compiled when the message path loads.

Given the additional overhead, it'll almost always be the case that "do" will run slower than alternatives. It's still pretty fast, but every clock cycle saved can go into a more powerful feature later on, so I'm a big fan of trimming runtime overhead whenever practical.

Post Reply