Understanding Lua tables in Corona SDK

Posted by

In Corona, you use the Lua programming language to do everything. Thus, it’s equally as important to understand Lua as it is to understand the individual Corona-specific concepts and API’s, such as the Event Model we went over last week.

One common source of confusion comes with one of Lua’s most powerful features: Tables.

What Are Tables?

If you’re familiar with other programming languages, then most likely, you’re already familiar with arrays and dictionaries. In Lua, a table is a mixture of both (which is why they are so flexible and powerful).

If the Corona SDK is your first foray into the programming world, however, the description above probably means nothing to you. In that case, you can think of a table as a dresser.

The drawers of the dresser would be known as “keys”, and the stuff (data) you’d put into the drawers is what’s known as the “value”. Where Lua tables differ from real drawers, however, is that you can place complete dressers (tables) within the individual drawers!

Before we go any further, let’s break down what you’ve learned so far:

  • Tables hold data (aka “stuff”). Data can be of any type, to include functions.
  • Tables can also hold other tables.
  • A “key” is the location where data is stored (like a drawer).
  • A “value” is the data that’s stored in a specific key.

And that’s probably the most basic explanation of Lua tables as you can get. In the following sections, I’ll show you how to define tables, how to store/retrieve the data within tables, and also how to use tables in conjunction with a “for” loop.

Defining Tables

And by defining, of course, I mean creating a table so you can use it whenever you want. For now, I’ll focus on creating a blank table, with no data in it. This is going to be our brand new dresser:

    local myTable = {}

A table is just another variable in Lua, so it’s defined the same way: just a variable name separated by an equals sign and the data you want to store in the variable.

The way Lua can tell it’s a table is, you guessed it, because of the brackets. Anywhere you see an opening bracket ( “{” ) in Lua, you know it’s a start of a table. The end of a table is always denoted by a closing bracket ( “}” ). You’ll see these all along, many times as arguments within functions, so it’s important for you to be able to identify them as tables whenever you see them.

Now that you have a blank table (myTable), it’s time to start storing stuff in it! Next I’ll go over the different ways to store data into a table, and also how to retrieve that data.

Tables as Arrays

Below are three different ways you can use a table as a numerical array. Each “method” shown below is completely identical. They are simply three ways to do the same exact thing.

The fourth method is exactly the same as the third, but it shows how line breaks aren’t necessary–you’ll see this one a lot when passing tables as arguments to functions.

METHOD 1:

    local colorTable = {}

    colorTable[1] = "blue"
    colorTable[2] = "red"
    colorTable[3] = "yellow"
    colorTable[4] = "green"
    colorTable[5] = "purple"

    print( colorTable[3] )  -- output: "yellow"

METHOD 2:

    local colorTable = {
        [1] = "blue",
        [2] = "red",
        [3] = "yellow",
        [4] = "green",
        [5] = "purple"
    }

    print( colorTable[3] )  -- output: "yellow"

METHOD 3:

    local colorTable = {
        "blue",
        "red",
        "yellow",
        "green",
        "purple"
    }

    print( colorTable[3] )  -- output: "yellow"

METHOD 4:

    local colorTable = { "blue", "red", "yellow", "green", "purple" }

    print( colorTable[3] )  -- output: "yellow"

Once again, the examples shown above all produce the same thing. A table with five different keys, all with the same value. As a Corona developer, you’ll see every single one because they all depend on personal preference.

When a table is used as a numerical array, the keys are all numerical values that go in order (starting from 1, not 0 as with most other programming languages). The print statement in each example (above) shows you how to access data in a table by placing their index number between square brackets ( “[]” ).

Also remember, whenever you define a table, keys are always separated by commas, with the final key not requiring one.

To get the total count of a table with numerical keys, you can do so by using the ‘#’ sign in front of the table name, like so:

print( #colorTable )    -- output: 5

Tables as Dictionaries

Lua tables can also behave like dictionaries from other programming languages (aka, “associative arrays”). Below is an example of a table behaving like a dictionary:

    local colorTable = {
        sky = "blue",
        grass = "green",
        water = "blue",
        lava = "red"
    }

    colorTable.dirt = "brown"

    -- Accessing the data:

    print( colorTable.grass )   -- output: green

    print( colorTable["dirt"] ) -- output: brown

In the above example, you can see the keys are NOT defined numerically, and that’s the main difference here. Sometimes, data is easier to identify using this method because of the way you’re able to access the data.

Instead of accessing data using numbers, you can “associate” the keys with words instead. In the example above, you see two different methods of accessing the data:

    colorTable["sky"]

    -- and...

    colorTable.sky

The two methods shown above are exactly the same–just two different ways to access the same data. And just as with numerical keys, you can add keys later on, as you can see with the dirt key being added after the table was already defined.

And speaking of flexibility, although Lua tables can behave like arrays and dictionaries, they can also behave like both at the same time. If you want, you could mix numerical keys with string-based keys, though this would make for a very confusing table structure. Normally, it’s best to go with either or.

Data Types

As mentioned before, tables can hold any kind of data within it’s individual keys. That means you can store additional tables, functions, and function references with the keys of a table, as well as the more common numbers and strings.

Here’s an example of how to store a table within a table (and how to access the data):

    local people = {
        { name="Bob", age=32, gender="male" },
        { name="Jane", age=29, gender="female" }
    }

    print( people[1].name )     -- output: Bob

    print( people[2]["gender"] )    -- output: female

There is no limit to how many tables you can store within other tables.

Another complex form of data you’ll see stored within the keys of a table are functions and references to other functions. Here’s an example of a reference to a function stored in the key of a table:

    local function helloWorld()
        print( "Hello World!" )
    end

    local myTable = {
        name = "Bob",
        func = helloWorld
    }

    myTable.func()  -- output: Hello World!


    ----------


    local function helloWorld()
        print( "Hello World!" )
    end

    local myTable = { 100, 100, helloWorld, true }

    myTable[3]()    -- output: Hello World!

And here’s how you would store an actual function (not a reference) in a table’s key:

    local myTable = { 100, 100, function() print( "Hello World!" ); end, true }

    myTable[3]()    -- output: Hello World!

As you’ve probably already figured out by now, each key within a table is no different than any other variable in Lua. You can store anything you want within it. That’s the best way to look at it.

When tables start getting big and confusing, the best advice I can give is to just look at what’s between the commas separately, as if it is on a line of code by itself. From there, your confusion should start clearing up.

Tables and Loops

One of the most common purposes of using tables over regular variables is the ability to “iterate” over the keys of a table with a loop.

Below is an example of how to iterate through a table with numerical keys:

    local myTable = { "blue", "red", "yellow", "green", "white", "purple" }

    for i=1,#myTable do
        print( myTable[i] )
    end

    -- OUTPUT:
    blue
    red
    yellow
    green
    white
    purple

With everything that I’ve went over so far, the above code should be pretty clear. Iterating over the contents of a table with numerical keys is pretty straight-forward.

However, what if your table has key names instead of numbers?

For that, we’ll use the pairs() function (which returns two variables):

local colorTable = {
    sky = "blue",
    grass = "green",
    water = "blue",
    lava = "red",
    dirt = "brown"
}

for key,value in pairs(colorTable) do
    print( key, value )
end

-- OUTPUT:
sky     blue
grass   green
water   blue
lava    red
dirt    brown

If a table uses names to identify the keys, then you can’t simply get the count and iterate over the keys numerically. Instead, you use the pairs() function with tables that don’t have numerical keys (just as you see in the example above).

Further Reading

To get a more complete, well-rounded understanding of tables in Lua, please visit the following two web pages (both of which were extremely useful to me when I was learning):

The more you see them and use them “out in the wild”, the more clear tables will become. When you finally have a real need for tables is when their power and flexibility will really shine through.

Feel free to post your questions in the comments section, I’ll try my best to respond to them as they come (be sure to do a quick skim of the comments to make sure your question wasn’t already asked!).

Ready to get started?

Create amazing games and apps for iOS & Android

38 Comments

Rob MiracleJune 21st, 2011 at 10:20 am

Very well done Jonathan!

carlos m. icazaJune 21st, 2011 at 12:57 pm

I even learned from reading this. Thanks Jon.

C.

Nick WJune 21st, 2011 at 1:57 pm

Nice one, thanks Jon.

Just a quick query does “Joe” turn into “Bob” because of a typo (or have I missed something?)

Very clear explanation, I’m not a programmer but could understand it.

Thanks

Nick

local people = {

{ name=”Joe”, age=”32″, gender=”male” },

{ name=”Jane”, age=”29″, gender=”female” }

}

print( people[1].name ) — output: Bob

print( people[2]["gender"] ) — output: female

Jonathan BeebeJune 21st, 2011 at 2:08 pm

@Nick: Nice catch! I’m not sure how or why his name got changed, lol. I updated the article.

RobJune 21st, 2011 at 3:47 pm

Jon,

These tutorials are great and helping a lot of us get to grips with Lua & Corona. Could I suggest a metatables tutorial and using them for OO in Lua? I use these techniques in my code but I don’t really understand what is really going on ;-)

Cheers!

Rob

AltafJune 21st, 2011 at 6:42 pm

hi Jon,

Thanks for this. MY suggestion is to also to consider a coordinate , scaling tutorial based on best practices for creating apps which can run both on iOS and android.

Keep up the good work.

MoJune 21st, 2011 at 9:58 pm

WOW! Thank you. Great stuff. Just a quick question about tables. Let say I want to setup a sprites which have position x and y. Could I use something like this:

sprite[1].x = 1000
sprite[1].y = 10
sprite[2].x = 2000
sprite[2].x = 4000
……

Thanks again for wonderful tutorials. I will also suggest one about timers and when they actual get triggered in a lua file(when they are declared or when the lua initialization is finished)

Mo

Jonathan BeebeJune 21st, 2011 at 10:07 pm

@Mo: Yup, you can definitely do that. Just make sure that “sprite” is a table before you start assigning values to its individual keys. Example:

sprite = {}

Also, in your example, sprite[1] and sprite[2] are also tables, because you are assigning values to their individual keys (x & y).

And thanks for the suggestions everyone.

PiyushJune 21st, 2011 at 10:48 pm

You have removed all the doubts about Tables.

MoJune 21st, 2011 at 11:26 pm

Cool. Thanks Jon

Mo

ChrisJune 22nd, 2011 at 12:48 am

Usefull post, Jon!

Maybe you should mention removing tables aswell (though i guess nil’ing them will work fine ;) )

Adrian EraldoJune 22nd, 2011 at 8:21 am

Thanks Jon!
Loud and clear.

paulJune 22nd, 2011 at 10:29 am

Nice – a clear and succinct definition of tables. Thanks Jonathan!

LeonJune 22nd, 2011 at 7:43 pm

Good one Jon. I have gone back to my game and started using tables now.

DanJune 23rd, 2011 at 5:45 am

Is it possible to remove an item from a table/array like pop it off the list?

I’m planning on storing a bunch of levels in a table and randomly picking one, then popping it off the table so it can’t be picked again in the same session.

Thanks.

DanielJune 23rd, 2011 at 6:04 am

@Jonathan Beebe It would awesome if you could write a tutorial about modules and how to use them. I know that I can’t be the only one still lost on them.

Jonathan BeebeJune 23rd, 2011 at 11:24 am

@Dan: Yes, you can do that. Just use table.remove( table, position ) — I should’ve went over that in the article!

You can also just set the key to nil, for example:

myTable[3] = nil

or…

myTable.favoriteColor = nil

@Daniel: Great idea! I’ll definitely add that to the list of upcoming topics. Right now I’m juggling collisions or external modules.

arma9June 23rd, 2011 at 11:37 am

Why sometimes it used in if block this format, by example:

local colorTable = {
sky = “blue”,
grass = “green”,
water = “blue”,
lava = “red”,
dirt = “brown”
}

–Here why???
for _,value in pairs(colorTable) do
print( key, value )
end

Jonathan BeebeJune 23rd, 2011 at 11:41 am

@arma9: Not exactly sure what you’re asking, but the table you are showing me cannot be indexed numerically, therefore you have to use the pairs() function, which returns two variables: a key, and a value (rather than just an index number, when dealing with numerically indexed tables)

AlexJune 28th, 2011 at 5:00 pm

please give a short tutorial on OO best practices

GaretJune 29th, 2011 at 6:54 am

I use tables for pretty much everything! My character = a table, his weapons = a table.

It’s very useful to layout your weapons and pickups as tables, such as:

myGun = {}
myGun.sprite = mySprite
myGun.damage = damage

etc

Then I can just assign it to my character like:

myCharacter.weapon = myGun

Then whenever I want to access something like damage I can simply call:

myCharacter.weapon.damage

They make like so much easier :)

GaretJune 29th, 2011 at 6:54 am

life* not like

MoJuly 13th, 2011 at 12:20 pm

Hello Jon

One more question if I may: how would you make a table of sprites? For instance sprites ={}
sprites[1].x = 100, sprites[1].y = 100, but about attaching an image to that table element?

At this I am using sprite1, sprite2 images and their x and y coordinates but I will love to use a table so to make my code more general.

Thanks a lot for any pointers

Mo

MoJuly 13th, 2011 at 5:55 pm

EDIT: Hi Jon. Forget it. I think I figure out ( I should have simply search better this great forum). I will come back here if I have still issues.

Thanks for a great post again!

Mo

MichelleJuly 18th, 2011 at 9:34 am

Jonathan,

Thanks for the post but I do have a question. I am a newby and was still able to catch on to alot of your docment but need some clarity. My gameboard has 16 spaces and I have 16 gamepieces. To complete this game the game pieces will form a specific pattern on the board. This pattern can change but overall it still comes down to the same logic with pieces shifted slightly. I thought about your game array you showed and started doing a ( “1″, “2″, through 16) but then was not sure how to progress from that. How do I know when a piece has landed on a specific spot on the board and once all the pieces are on the board, how do I tell whether the pattern is correct via the logic?

fjalJuly 24th, 2011 at 8:38 am

hi,

how can i get the data which is a table inside a table, i mean like this:

t = { {a, b, c}, {d, e, f} };

print(t[1]) —–>>> {a, b, c}

BUT
how can i print just the letter “a”?

TIA

Jonathan BeebeJuly 25th, 2011 at 10:52 am

To print the letter “a” in your example, you do this:

print( t[1][1] )

ZaidiSoftAugust 5th, 2011 at 5:34 am

Hey Jon,

Great tutorial and helped me a lot as newby on Lua.

Quck question here. I am trying to make a dictionary app with audio translation included. How will I accomplish that. I think using a table will be a great way to go but how can I associate a word with audio file and access it.

SeanAugust 8th, 2011 at 6:35 pm

Jon,

How might I store various image files in a table and call them at random? Any suggestions on how to code this would be greatly appreciated.

Thanks,
Sean

Jonathan BeebeAugust 8th, 2011 at 8:34 pm

Hi sean, here’s the most basic way I could think to do that:

local imgTable = {
“image1.png”,
“image2.png”,
“image3.png”
}

local randN = math.random(1,3)
local imageObj = display.newImage( imgTable[randN] )

SeanAugust 8th, 2011 at 10:24 pm

Thanks Jon,

Your suggestion worked like a charm!

Sean

luizAugust 31st, 2011 at 9:19 am

hi,
i want to see a “simple shooter” demonstrating how to crate
a enemies table,a shot tabe and a ship table and how it works all together.
there is a HUGE difference between just read the “syntax” in lua docs and
and have an example demonstrating how tables works in a game.

Nicholas GoldenSeptember 28th, 2011 at 11:30 pm

Jon you are a pimp!

I’ve been avoiding tables like the freaking plague! I’ve made a game, i’ve got my structure and then I had to think about saving data like score, level completed etc. Since I never programmed anything before lua/corona, I knew I needed to learn tables.

This really helped me out, I’ve read through this several times and my guess I’ll be reading through this over and over again basically using as my reference doc for tables. It’s really good!

Off to go build a dresser with a dresser containing a dresser. Whoa. lol.

-Nick g

Rodrigo RSCdevOctober 29th, 2011 at 10:08 pm

Hello Jonathan,

Just would like to say something…”Thank You Mate!”

Help like this article is invaluable.

Regards,
Rodrigo.

Binod SumanDecember 28th, 2011 at 5:04 am

Hi,

Very thanks for good tutorial and best thing is that you have explained in very basic way. One small question, if I have one table and that is not numerical index based then how to remove item from that table.

Example:

local person = {}
person.name=”Jonathan”
person.friend=”Binod”
person.mobile=”9999999999″

Now I have to remove mobile info from person table?

Thanks again from sharing very nice tutorial.

Binod Suman
Bangalore, India

Marco OtteFebruary 3rd, 2012 at 1:55 am

Hi,
I was wondering if I can dynamically define tables.
So something like this:

local theName = {“tableName1″, “tableName2″}
local theName[1] = {}

Then having not only the initial table called ‘theName’ but also a table called ‘tableName1′.

On the Net I found some references to:

local _G['theName[1]‘] = {}

but that doesn’t seem to work with the Corona SDK.

Thanks!

danielFebruary 8th, 2012 at 1:36 pm

hi can som one HELPPPPPPPPPP ME i try to spawn 2 monsters and i cant
here is the code i need this because i need to spawn like 30 diferent characters with same properties

local myTable = {“monster1″,”monster2″}
for i=1,#myTable do
local ( myTable[i])= display.newImage”images/mosntruos/monstruo”..i..”.png”)
end

milahbApril 5th, 2012 at 11:53 am

very interesting stuff indeed

Leave a comment

Your comment