Array index - any tricks for using numbers or strings?

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
heyvern
Posts: 30
Joined: Sun Feb 21, 2010 12:38 am

Array index - any tricks for using numbers or strings?

Post by heyvern » Thu Mar 11, 2010 4:32 am

I am creating an application in RR that reads another application file format. I have a global variable array that contains a one word string and is indexed by a number value. Each item is used in my application might need to be looked up as either a word or a number. Unfortunately RR can't use the string value as the index or the number as the index interchangebly. In some places I only have a number value to look up the "word" but in some places I have the "word" that needs to get the number.

As a workaround and since the list is small, I have two duplicate sets of values in the array. My question is if anyone has a way or technique to doing some kind of cross referencing that might work so I don't have to include double sets of indexes in my array. The good news is this is just a curiosity for me at the moment... to be efficient. This array will be set once and is static and never changes. It contains static unchanging values and is a way to quickly find the type of info the number or word represents so it can be "written" to an exported file format.

I am using a single function, that I pass either a number or word from the file format and return either a number or word back depending on what is needed.

Below is the array indexed by number values:
(And YES, number 8 is "missing". Don't ask me why. There are only 8 layer types in the file format but 8 is not used for some reason I don't know. The "Sound" layer type was just added in the latest version so that might be a reason.)

Code: Select all

aLayerTypes[1] -- contains "Vector"
aLayerTypes[2] -- contains "Image"
aLayerTypes[3] -- contains "Group"
aLayerTypes[4] -- contains "Bone"
aLayerTypes[5] -- contains "Switch"
aLayerTypes[6] -- contains "Particle"
aLayerTypes[7] -- contains "Note"
aLayerTypes[9] -- contains "Sound"
Duplicated reversed array entries:

Code: Select all

aLayerTypes["Vector"] -- 1
aLayerTypes["Image"] -- 2
aLayerTypes["Group"] -- 3
aLayerTypes["Bone"] -- 4
aLayerTypes["Switch"] -- 5
aLayerTypes["Particle"] -- 6
aLayerTypes["Note"] -- 7
aLayerTypes["Sound"] -- 9
And this is my simple function:

Code: Select all

function LayerTypes layerVal
  if isNumber(layerVal)
    return aLayerTypes[layerVal]
  else
    put quote & layerVal & quote into layerVal
    return aLayerTypes[layerVal]
  end if
end LayerTypes
So I am wondering if this is a reasonable solution or is there a better one?

bn
VIP Livecode Opensource Backer
VIP Livecode Opensource Backer
Posts: 4163
Joined: Sun Jan 07, 2007 9:12 pm

Re: Array index - any tricks for using numbers or strings?

Post by bn » Thu Mar 11, 2010 12:25 pm

heyvern,
you could put your values into a multidimensional array. Advantage only one array, disatvantage a little more complex to grasp.
Into a button

Code: Select all

on mouseUp
   put "Vector,Image,Group,Bone,Switch,Particle,Note,,Sound" into tWordy
   put "1,2,3,4,5,6,7,,9" into tNumbers
   put "" into aLayerTypes
   repeat with i = 1 to the number of items of tWordy
      put item i of tWordy into tTheWord
      put item i of tNumbers into tTheNumber
      if tWordy is  "" then next repeat
      
      put tTheNumber into aLayerTypes["returnAsNumber"][tTheWord ]
      put tTheWord into aLayerTypes["returnAsWord"][tTheNumber]
      
   end repeat
   -- breakpoint
   set the uLayerArray of this stack to aLayerTypes
end mouseUp
for the setUp of the array. If you want to look at the array deblock the breakpoint and have a look at the array in the debugger.
Test of the array (make a field first)

Code: Select all

local aLayerTypes

on mouseUp
   put the uLayerArray of this stack into aLayerTypes
   if aLayerTypes is not an array then 
      answer "the array must be filled first"
      exit mouseUp
   end if
   
   put "" into field 1
   put "Vector,Image,Group,Bone,Switch,Particle,Note,,Sound" into tWordy
   put "1,2,3,4,5,6,7,,9" into tNumbers
   --breakpoint
   repeat with i = 1 to the number of items of tWordy
      put item i of tWordy into giveMeTheNumber
      put item i of tNumbers into giveMeTheWord
      if giveMeTheWord is "" then next repeat
      
      
      put LayerTypes(giveMeTheNumber) & " = " & layerTypes(giveMeTheWord) & return after field 1
     
   end repeat
   
end mouseUp

function LayerTypes layerVal
   if isNumber(layerVal) then
      return aLayerTypes["returnAsWord"][layerVal]
   else
      return aLayerTypes["returnAsNumber"][layerVal]
   end if
end LayerTypes
this script into another button.
Since your list is rather short for maintainability it is maybe easier to go the item way:

Code: Select all

on mouseUp
   put "" into field 1
   put "Vector,Image,Group,Bone,Switch,Particle,Note,,Sound" into tWordy
   put "1,2,3,4,5,6,7,,9" into tNumbers
   --breakpoint
   repeat with i = 1 to the number of items of tWordy
      put item i of tWordy into giveMeTheNumber
      put item i of tNumbers into giveMeTheWord
      if giveMeTheWord is "" then next repeat
      put LayerTypes(giveMeTheNumber) & " = " & layerTypes(giveMeTheWord) & return after field 1
   end repeat
end mouseUp

function LayerTypes layerVal
   -- a little error checking
   if layerVal is "" then return "error, no value passed"
   
   -- you could put this into a gobal or a script local variable
   put "Vector,Image,Group,Bone,Switch,Particle,Note,,Sound" into tWordy
   put "1,2,3,4,5,6,7,,9" into tNumbers
   
   if isNumber(layerVal) then
      return item (itemOffset(layerVal,tNumbers)) of tWordy
   else
      return item (itemOffset(layerVal,tWordy)) of tNumbers
   end if
end LayerTypes
I think the item way is also very fast. If you have more items an array would probably be more appropriate.
I attach the example stack
regards
Bernd
Attachments
ArrayMulti-ItemOffset.rev.zip
(1.77 KiB) Downloaded 249 times

bn
VIP Livecode Opensource Backer
VIP Livecode Opensource Backer
Posts: 4163
Joined: Sun Jan 07, 2007 9:12 pm

Re: Array index - any tricks for using numbers or strings?

Post by bn » Thu Mar 11, 2010 2:21 pm

heyvern,
coming to think of it, my previous array solution using a multidimensional array is not necessary.
Just use a one-dimensional array as keys: the numbers and the words. The content of the key is the opposite.
This makes the function realy simple

Code: Select all

function LayerTypes layerVal
   return aLayerTypes[layerVal]
end LayerTypes
since you either call it with a number and it returns the word or you call it with the word and it returns the number.
I attach a demo stack for that too.
It helps to think about stuff....
It was a nice little coding exercise.
regards
Bernd

Edit: you might even leave out the function call and process this inline since now it would be just one line of code.
Attachments
MonoArray.rev.zip
(1.41 KiB) Downloaded 266 times

heyvern
Posts: 30
Joined: Sun Feb 21, 2010 12:38 am

Re: Array index - any tricks for using numbers or strings?

Post by heyvern » Fri Mar 12, 2010 5:37 am

Yeehaa! Great solution AND a stack to go with it. ;) you made it look so easy. The code is so simple. My current solution was similar but had like 3 times the code. You are right about the array. The data set is way too small to actually benefit from a full blown cross dimensional array. Using "repeat with" instead of "repeat for each" shouldn't be a speed hit considering the short list. My concern in the beginning was that there are so MANY layers. If the "repeat with" has to run for each layer it could be very slow. I assume that this array only needs to be generated one time and can be referenced over and over.

I have decided to avoid trying to automate so much of my application. I had planned to create functions that would be universal and not need lists of "key words". I was trying to use regex and try to make one function find every possible combination of text chunks. It's proving to be way to much work for very little benefit. I have the entire file format and know exactly what "words" are in each section. I can create small list arrays like this to save and retrieve data.

The files read in have the same data sets and it's always in the same order etc. So each part of the file has "predefined" lists of words. I can create multiple lists and/or arrays for each unique section. I was trying to hard to avoid having to "hard code" those items. I was trying to find them with regex without knowing what they are. I have found that this is just plain silly and not working for me. Too many areas of the file are identical and it's more effort avoiding "catching" the wrong section.

redpill
Posts: 21
Joined: Fri Jan 08, 2010 10:38 pm

Re: Array index - any tricks for using numbers or strings?

Post by redpill » Fri Mar 12, 2010 9:20 am

To Bernd: Very nice solution, indeed!

I am a beginning Rev user just learning the language and found this question to be a great learning opportunity. I know I learned a great deal about Rev's array handling capabilities. Also, I would like to contribute to the forum as much as possible. This is my first real contribution! I hope you find it useful.

My solution is implemented using a multi-dimensional array. Although my approach may not be as simple as Bernd's solution, I find it personally easier to understand, since the array is organized hierarchically.

There is one stack function, one button handler to call the function, and a button handler that creates the array.

The array is arranged to have a "primary key" named "Layer Types". This arrangement allows for the use of multiple data stores in a single array. For example: Currently, we are storing information about "Layer Types." You may want to store other information. Just create another 1st level key.

The secondary key is numeric. Although this example uses manually typed numeric keys, they could be coded into a counter.

Finally, the third key is the name of the data item that will be stored in that location.

Code: Select all

global gLayersArray

on mouseUp
   put empty into gLayersArray
 
   put 1 into tArray[1]["layerNum"]
   put "Vector" into tArray[1]["layerName"]
   
   put 2 into tArray[2]["layerNum"]
   put "Image" into tArray[2]["layerName"]
   
   put 3 into tArray[3]["layerNum"]
   put "Group" into tArray[3]["layerName"]
   
   put 4 into tArray[4]["layerNum"]
   put "Bone" into tArray[4]["layerName"]
   
   put tArray into gLayersArray["Layer Types"]
   
end mouseUp
Next is the function call. I just used a field to type in either a layer's number OR name. Here is the button handler to call the function:

Code: Select all

on mouseUp
   put field fldFindLayer into theFindValue
   put findLayer(theFindValue) into field fldResult
end mouseUp
Finally, here is the impressive 8) function that will locate a layer's name or number. I'm sure this could be abstracted more, but I wanted to keep it readable.

Code: Select all

global gLayersArray

function findLayer theLookup
   
   if theLookup is an integer then
      put "layerName" into itemResultKey
      put "layerNum" into itemMatchKey
   else
      put "layerNum" into itemResultKey
      put "layerName" into itemMatchKey
   end if
   
   --Scan the array
   repeat for each key tKey in gLayersArray["Layer Types"]
      if gLayersArray["Layer Types"][tKey][itemMatchKey] = theLookup
      then return gLayersArray["Layer Types"][tKey][itemResultKey]
         
   end repeat
      
end findLayer
That's it. :)

The more I use Revolution, the more impressed I am with its power. Although, this exercise did cause me to blurt out a few expletives, as the revTalk syntax is tricky.

bn
VIP Livecode Opensource Backer
VIP Livecode Opensource Backer
Posts: 4163
Joined: Sun Jan 07, 2007 9:12 pm

Re: Array index - any tricks for using numbers or strings?

Post by bn » Fri Mar 12, 2010 12:28 pm

heyvern,
heyvern wrote:I assume that this array only needs to be generated one time and can be referenced over and over.
Yes that is the whole idea. Once created I put the array into a custom property. This is saved with the stack, so if you start your stack an "on openstack" handler can put the custom property into a global variable and you have access to the array all over the place in that fast global variable.

@redpill, nice and elaborate example, but I think it is too much for what heyvern has in mind. But it is a nice example how to build multi-dimensional arrays. In my first attempt I used 2 approaches: one with a mulitidimensional array and a solution purely based on an item list for the numbers and the words and do a look-up with itemOffset. There are only 8 items in each list, so if one does not feel comfortable with arrays one could use this "low tech" approach.
regards
Bernd

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

Re: Array index - any tricks for using numbers or strings?

Post by FourthWorld » Fri Mar 12, 2010 1:30 pm

heyvern wrote:Yeehaa! Great solution AND a stack to go with it. ;) you made it look so easy.
If we were giving out awards here I'd nominate Bernd. He's been enormously helpful to so many people, coming through time and again with sample code like that. Thank you, Bernd, for you many significant contributions here.
Richard Gaskin
LiveCode development, training, and consulting services: Fourth World Systems
LiveCode Group on Facebook
LiveCode Group on LinkedIn

bn
VIP Livecode Opensource Backer
VIP Livecode Opensource Backer
Posts: 4163
Joined: Sun Jan 07, 2007 9:12 pm

Re: Array index - any tricks for using numbers or strings?

Post by bn » Mon Mar 15, 2010 11:30 am

Richard,
thank you for the kind words.
There are quite a few on this forum contributing. Not the least a certain Richard Gaskin :wink:
The fun part of trying to help is that it is sometimes a bit like blind-chess, at times mind reading, and and an opportunity to get to know all kinds of different problems and solutions.
regards
Bernd

Post Reply