# Learn Lua the Hard Way – Tables

Tables are the most important data structure in Lua thanks to their flexibility, hence we dedicate an entire post to the use of tables. In this tutorial, you will learn how to create and manipulate tables and dictionaries and how to iterate over a table using for and while loops.

- 27 February, 2011 -
- Article, Lua -
- Tags :
- 21 Comments

### 1. Other Tutorials

Chapters 1–5 → An introduction to Lua.

Chapter 11. → The project team problem part 1

### 2. Table of contents

- Chapter 6: Tables
- Chapter 7: Loops
- Chapter 8: For Loops with Tables
- Chapter 9: Dictionaries
- Chapter 10: Table Functions

### 3. Chapter 6: Tables

Being able to work with singular pieces of data like numbers and strings is all good and fun, but sometimes we may need to use multiple objects at the same time. What if we wanted to find the average height of a bunch of cats so we can make crude references to “long cat is long”, but we need some kind of exhibitionary evidence? Sure, if we have five cats, we can just put them each in a separate variable and take the average of them:

cat1 = 10 cat2 = 11 cat3 = 12 cat4 = 8 cat5 = 100 -- LONG CAT IS LONG print("The average length between these cats is ", (cat1 + cat2 + cat3 + cat4 + cat5) / 5)

But what if a sixth cat comes along? Well you’re going to have to add it into the group as well because he’s meowing ever so cutely and you like to imagine yourself as the protector of cat equality. But upon seeing the sixth cat all smug and high that it was allowed into this exclusive club, cat7 and cat8 became discontent and they too try to “fit in” with everyone else… Sooner or later, you’re just going to be all like “fuck this, I’m not gonna be a bitch to some cats” and stop adding cats into your program because it’s been a long day, the meowing is getting on your nerves, and you’ve realized that the “long cat is long” joke is getting kind of old. But what about poor ole cat256? He’s got no job and an entire family of kittens and Ms. cat256 to feed. You’ll be labeled an enemy of the working cats and will be hated for the rest of your life (at least by 4chan).

Luckily, there’s a solution to situations where you either need to work with a massive amount of data or need to be able to grow your data once the program begins running.

Tables are magical entities in Lua. You can put anything you want in them, for example, your mother’s phone number, your employer’s address, the cost of purchasing a shotgun at your local friendly K-mart, and the probable date that you will receive your pink slip from the said employer. All in all, a table’s use can range anywhere from questionably legal to full-on awesome. In this case, we will be putting cats into our table:

cats = {10, 11, 12, 8, 100}

Here, we use the usual syntactical construct for assigning variables. However, rather than a number or a string, we’re assigning a table to the variable **cats**. A table is a grouping of elements that starts with a left bracket ({) and terminated with a right bracket (}). Individual elements of this table are separated using commas (,).

Elements of this table can also be retrieved later on using the “subscript notation”.

cat1 = cats[1] cat3 = cats[3]

In the above code, the square brackets ([n]) is a subscript, which in formal mathematics denote the n-th element of a sequence or a table. By putting the subscript ([n]) after the table name (cats), we’re **indexing** into the table, or we’re returning the n-th element of the table.

So in order to find the average of these five cats, we would need to write:

cats = {10, 11, 12, 8, 100} print("The average height between these cats is ", (cats[1] + cats[2] + cats[3] + cats[4] + cats[5]) / 5)

Output:

The average height between these cats is 28.2

#### Additional exercises:

- If you need to add a sixth cat whose height is 28, what would be the average of all six cats?
- Remember how you can use the # symbol to find the length of a string? Try it on a table as well. What will happen if you printed
`#cats`

? - Can you add different types of data into a table? For example, can you have {“Lee”, 19}?
- What about adding tables into tables? Can you think of situations where this might be useful?

### 4. Chapter 7: Loops

As you can see from the above example, manually indexing into a table isn’t very elegant or efficient. What we need is a way for the computer to loop through every element of that table and then take the sum of these elements. It’s a good thing that we’re using a programming language to do this.

#### While Loops

A while loop will keep on executing the same thing until certain conditions or predicates are satisfied.

while CONDITION do ... end

In this case, as long as `CONDITION`

is true, … will execute. But as soon as CONDITION becomes false, the loop will stop.

x = 1 while x < 10 do -- (x < 10) is the CONDITION print(x) x = x + 1 -- We need to increase x by one each time. end

Output:

1 2 3 4 5 6 7 8 9

Because (10 < 10) is false, as soon as x becomes 10, the loop exits, so 10 is never printed out.

#### For Loops

There are two ways to create a loop using the `for`

keyword, we will focus on the more general method.

If you want to loop through a range of numbers (for example, going from 1 to 100), you can use the following construct:

for i=1, 10, 1 do print(i) end

Output:

1 2 3 4 5 6 7 8 9 10

In this example, i=1 is the starting number, 10 is when the loop ends, and the last 1 is the step size. Thus, if we want to print all of the odd numbers, we can use

for i=1, 10, 2 do print(i) end

Output:

1 3 5 7 9

Accordingly, we can also loop through every single element of a table if we know the size of that table. We can find the size of a table using the hash mark operator (#).

cats = {10, 11, 12, 8, 100} sum = 0 for i=1, #cats, 1 do sum = sum + cats[i] end print("The average height between these cats is ", sum / #cats

Output:

The average length between these cats is 28.2

The (#cats) returns a number that corresponds to the size of the table (5), and the for loop iterates from 1 to #cats (5) and adds each element from the table of cats into the variable sum. We then take the average of sum by dividing by the number of cats (#cats).

#### Additional exercises:

- Print out all of the even numbers between 1 and 10. How about between 1 and 11? Do they display the same set of numbers?
- Print every number backwards from 10 to 1.
- Add a sixth number into the cats table and find the average of that table now. How much code did you have to edit? Can you see why for loops work really well with tables?
- In mathematics, the factorial function of n returns the product of every number between 1 and n (factorial of 3 = 3 * 2 * 1, factorial of 10 = 10*9*8*7*6*5*4*3*2*1). Write a program that prints out the factorial of 100 (9.3326215443944e+157)
- If you write
`for i=1,100 do print(i) end`

, will you get an error? - What will happen if you write
`while true do print("Infinite loop.") end`

? - What happens if you write
`for i=1,2 do i=1 end`

? Will this produce an infinite loop? - What will happen if you write

`while true do`

? What does the break keyword do?

print("Infinite loop.")

break

end

### 5. Chapter 8: For Loops with Tables

A second construct for a `for`

loop will only work with tables. This kind of a loop takes advantage of a feature in the language called an iterator (or generator), which is an advanced topic. But at its simplest, we can iterate through every element of a table using the ipairs() function.

for i,v in ipairs(cats) do print(i, v) end

Output:

1 10 2 11 3 12 4 8 5 100

As you may have already figured out, this for loop sets i as the counter (index) of the table and v as the value of the elements. This is nearly equivalent to:

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

#### Additional exercises

- Using only ipairs, find the average height of the cats.
- What will happen if you use
`for i,v in pairs(cats) do print(i,v) end`

? Compare the output between ipairs and pairs. - In probability theory / statistics, one can calculate the standard deviation of a set or a table of numbers by subtracting every element of a table with its average and taking the squareroot of the sum of the squares of each element. (IE: stdev of {1,2,3} = math.sqrt( (1-2)^2 + (2-2)^2 + (3-2)^2 ) where 2 is the average of that table. Write a program to calculate the standard deviation of
`{96, 100, 75, 58, 91, 78, 81, 85, 70, 69, 83, 74, 80} where math.sqrt(n) returns the square root of a number.`

. (Average = 80, Standard Deviation = 39.77)

### 6. Chapter 9: Tables as Dictionaries.

As we all know, a dictionary is a record that creates a mapping (relation) between a word and its definition. These types of relation in which one object is mapped to another is also very useful to programmers. Did you know that tables can be used as a dictionary for Lua data as well?

dictionary = {hello = "used to express a greeting ", world = "the earth or globe, considered as a planet"} print(dictionary["hello"], dictionary["world"])

In fact, you can also add in new definitions once you’ve declared the dictionary:

dictionary["cat"] = "a small domesticated carnivore "

And that these definitions can be of any type as well:

dictionary["lua"] = {"A programming language.", "The moon in Portuguese."}

And that dictionaries can be mixed with numerical indices:

dictionary["lua"] = {"A programming language.", "The moon in Portuguese.", category = "This is also a dictionary :O"}

In fact, a dictionary doesn’t have to be defined using strings, you can use anything:

dictionary[1] = "A programming language." dictionary[{1,2,3}] = "wait, wtf is this?"

Note that when you’re using a numerical index, the dictionary doubles as a list so you can actually use ipairs to cycle through the elements:

dictionary[1] = 1 dictionary[2] = 2 dictionary[3] = 3 for i,v in ipairs(dictionary) do print(i,v) end

Output:

1 2 3

And if you want to cycle through all of the elements of the dictionary, you can use the pair function.

for key, val in pairs(dictionary) print(key, val) end

#### Additional exercises

- Write a dictionary that contains itself.
- One of the most useful dictionary used in the Lua language is the table that contains all of the global variables itself. Try the following:
`for key,val in pair(_G) do print(key) end`

. Now create a new variable –`a = 3`

. What is _G[“a”]? - If you have a dictionary
`o = {d = 3}`

, what will happen if you print`o.d`

? What about`_G.o.d`

? - Let’s say that you have a list of values
`{1,2,3,4,5}`

, what will happen if you do`print(unpack({1,2,3,4,5}))`

? What about`print(unpack({1,2,3,4,5,a = 6}))`

? - Earlier, we talked about how we can mix lists with dictionaries. What will happen if you execute the following code?
`for i,v in ipairs({1,2,3, a = "haha, I'm ruining everything", 4, 5, 6}) do print(i,v) end`

- What about
`{[1] = 1, [2] = 2, [3] = 3}`

- What about
`{1,2,3,4,5,[3] = "I'm in your list"}`

? - Oftentimes, you will see a shorthand for passing lists into functions. Find out what the following does:
`unpack{1,2,3,4,5}`

versus`unpack({1,2,3,4,5})`

- While Lua allows you to use tables as keys for dictionaries, this is generally not a good idea. Find out what the following produces:

`dict = {}`

dict[{1,2,3}] = 1

print(dict[{1,2,3}])

### 7. Chapter 10: Table Manipulation functions in the Standard Library

This chapter will focus on a few very useful table manipulation functions.

unpack (list, i, j)Returns the elements from the given table. This function is equivalent to

return list[i], list[i+1], ···, list[j]

Example

list = {1,2,3,4,5,6,7,8,9,10} print(unpack(list)) -- prints out 1 2 3 4 5 6 7 8 9 10 print(unpack(list, 2)) --prints out 2 3 4 5 6 7 8 9 10 print(unpack(list, 3, 5))--prints out 3 4 5

table.concat (table [, sep [, i [, j]]])Given an array where all elements are strings or numbers, returns table[i]..sep..table[i+1] ··· sep..table[j]. The default value for sep is the empty string, the default for i is 1, and the default for j is the length of the table. If i is greater than j, returns the empty string.

Example

list = {1,2,"a"} print(table.concat(list)) -- 12a print(table.concat(list,", ")) -- 1, 2, a print(table.concat(list,",", 2)) -- 2,a print(table.concat(list,"WEE",1,2)) -- 1WEE2

table.insert (table, [pos,] value)Inserts element value at position pos in table, shifting up other elements to open space, if necessary. The default value for pos is n+1, where n is the length of the table (see §2.5.5), so that a call table.insert(t,x) inserts x at the end of table t.

Example

list = {1,2,3} table.insert(list,4) -- list is now {1,2,3,4} table.insert(list,2,4) -- list is now {1,4,2,3,4}

table.remove (table [, pos])Removes from table the element at position pos, shifting down other elements to close the space, if necessary. Returns the value of the removed element. The default value for pos is n, where n is the length of the table, so that a call table.remove(t) removes the last element of table t.

Example

list = {1,2,3,4,5} table.remove(list) -- list is now {1,2,3,4} table.remove(list, 2) -- list is now {1,3,4}

table.sort (table)Sorts table elements in a given order, in-place, from table[1] to table[n], where n is the length of the table. If comp is given, then it must be a function that receives two table elements, and returns true when the first is less than the second (so that not comp(a[i+1],a[i]) will be true after the sort). If comp is not given, then the standard Lua operator < is used instead. The sort algorithm is not stable; that is, elements considered equal by the given order may have their relative positions changed by the sort.

Example

list = {5,2,3,6,1} table.sort(list) -- list is now {1,2,3,5,6}

#### Additional exercises

- There are no additional exercises for this module.

Next – problem solving

Pingback: Chapters 1–5 → An introduction to Lua. | CodingSnake()

Pingback: 26. Tables | coolcodea()

Pingback: cloud web service()

Pingback: affiliate marketing()