Using Tables in Lua

IF there are a series of conditions, most developers are tempted to use a series of if..then statements which can work, but in terms of extensibility and CPU cycles, this might not be a good way. This article would look at how tables can be used.

Let’s look at the example

 aspect = 1.5 -- or whatever calclated

 if aspect == 1.35 then
  pos1 = 10
 else if aspect == 1.5 then 
  pos1 = 20
 else if aspect == 1.6 then
  pos1 = 30
 else if aspect == 1.7 then
  pos1 = 40
 end

This could be an easy way, but it is not extensible, via external files (maybe in another article soon).

So how can this be managed any better or easier? Here is an alternative manner

 local tAspect = 
 {
  [1.35] = 10,
  [1.5] = 20,
  [1.6] = 30,
  [1.7] = 40,
 }

 aspect = 1.5
 pos1 = tAspect[aspect]

The way this code works is that the data is stored in a table from which we read it and set our variable.
There are a couple of things that are interesting in this code is that while declaring tables would look like

 local aTable = 
 {
  One = 1,
  Two = 2,
  Three = 3,
  Four = 4
 }

This can then be used as print(aTable["Four"]) which would display 4. However if we wanted to have an item into the table that was a number, we cannot simply have something like

 aTab = 
 {
  1 = 1,
  1.5 = 2,
  1.75 = 3
 }

as this will spawn an error, however if you use square brackets around the numbers, they allow for numeric key value pairs to be set in the tables. So the code above to work would look like

 aTab = 
 {
  [1] = 1,
  [1.5] = 2,
  [1.75] = 3
 }

Extending the data

This is fine, but what if someone wanted to have more data than just pos1, what if based on the aspect ratio of the screen one wanted to set a couple of more variables? Some developers will jump and create multiple tables which cab be used one for each variable. However the easier way would be to create a single table with multiple fields, like so

 aTable = 
 {
  [1.35] = {10, 10, 1, 5},
  [1.5]  = {20, 30, 2, 7},
  [1.6]  = {30, 5,  1, 2},
  [1.7]  = {40, 20, 4, 9},
 }

To use the data we use it similar as we did in our previous example, we now get a table instead of a value and we can then simply get get the data from that table.

 aspect = 1.6
 res = aTable[aspect]
 pos1 = res[1]  -- 30
 pos2 = res[2]  -- 5
 pos3 = res[3]  -- 1
 pos4 = res[4]  -- 2

If we need to name our data, we could have

 aTable = 
 {
  [1.35] = {pos1=10, height=10, speed=1, lives=5},
  [1.5]  = {pos1=20, height=30, speed=2, lives=7},
  [1.6]  = {pos1=30, height=5,  speed=1, lives=2},
  [1.7]  = {pos1=40, height=20, speed=4, lives=9},
 }

and we could then use

 aspect = 1.6
 res = aTable[aspect]
 pos1 = res["pos1"]    -- 30
 pos2 = res["height"]  -- 5
 pos3 = res["speed"]   -- 1
 pos4 = res["lives"]   -- 2

As you can see, we can add as many more entries as we want without having to bother with if..then type statements

How to code proof this

One could choose either the if..then or the table method we discussed above and let’s say that there is a new device with an entirely different aspect value, the if..then would not work and nor would the table method. From a personal experience, an app that I had created was made for a particular range of devices and then suddenly there were a couple of new devices which broke the app. The reason was simple as mentioned above. The new devices were not catered for.

We can cater for most of the devices almost like the if..else if..else in our case all it entails is that we can set the default values. This will thereby look like

 aspect = 1.6
 res = aTable[aspect] or {pos1=10, height=10, speed=1, lives=5}
 pos1 = res["pos1"]    -- 30
 pos2 = res["height"]  -- 5
 pos3 = res["speed"]   -- 1
 pos4 = res["lives"]   -- 2

In the second line, we have set the res to get the table entry corresponding to the aspect and if we have a new aspect that is not catered for, we would then pass it the default data of {pos1=10, height=10, speed=1, lives=5}.

We can have some more articles on using table in the coming days.

Social tagging: >

Comments are closed.