Last Updated:

Tables in Lua

Table properties:

  • T. is an object;
  • It can have an unlimited size;
  • T. are key-value pairs. In this case, both the key and the value can be any data type except nil.

Lua developers position tables as the leading tool for structuring data in their language.

Creating a table in Lois

Blank simple table

local t = {}

To access its field, the following syntax is used:


Example 1 with different types

t[1] = 10
t[Pushkin] = "poet"
t[3] = true

local function f()
return 1

t[f] = "function"
t["function"] = f = t is the same as t["me"] = t is a reference to itself
print(t["function"]()) - > 1

Identify a table when you create

local t = {1, 2, 3, x = 5, [Pushkin] = "poet"}

Example 2

t = {}
t[1] = "first" — new field with key 1 and the value "first"
t[2] = 20 – field with key 2 and value 20
k = "name"
t[k] = "Jane"
a = t[1] — assign a value "first"
b = t[2]
c = t["name"]

String keys t["name"] are easier to write down - = "name" is equivalent to t["name"] = "name"
a = is equivalent to a = t["name"]

Importantly! In case 1, a table field with the key "name" is presented (it is equivalent to t["name"]). The second expression is a field where the key is the identifier of the variable name. Let's consider the difference in more detail:

t = {}name = "somebody" t[name] = "Jane" - the value "Jane"a = t[name] is placed in the "somebody" field - variable a gets the value of the field "somebody" ("Jane")b = - variable b gets nilc = t.somebody - variable c gets the value of the field "somebody" ("Jane")

If there is no field with the specified key, accessing it returns nil:

t = {}
a = — variable a gets the value nil

As a result, you can delete a field by assigning it an empty nil:

t.second = nil

Populate the table when it is created. In {} we put the keys and values according to the example from the beginning of the article. Elements should be separated by commas or semicolons:

t = {["apple"]="apple", ["orange"]="orange", ["lemon"]="lemon"}

This is equivalent to the code below:

t = {} = "apple"; = "orange"; t.lemon = "lemon"

When working with string keys, you can omit the square brackets (and double quotation marks):

t = {apple="apple", orange="orange", lemon="lemon"}

You can create a table where the fields are also tables:

points = {
a = {x=20, y=1},
b = {x=40, y=2}



points = {}
p.a = {x=20, y=1},
p.b = {x=40, y=2}


If no keys were specified when the table was initialized, the language itself assigns key values starting with 1.

Importantly! Array addressing begins with 1 instead of 0.

local t = {3, 4, 5}
print(t[1], t[2], t[3]) — > 3, 4, 5

In order not to break the structure when working with array elements, you need to use the Lua table library.

local t = {1, 2, 3, 4, 5}
  1. table.insert(t, 6) — adds an element to the end of the array. Now t = {1, 2, 3, 4, 5, 6}
  2. table.insert(t, 0, 1) — inserts an element by index, shifting the remaining elements of the array. Now t = {0, 1, 2, 3, 4, 5, 6}
  3. table.remove(t, 3) — removes an item from the table at index 3 and shifts the remaining elements. Now t = {0, 1, 3, 4, 5, 6}

To calculate the size of an array, use #:

local count = #t

The # operator returns max the index of a continuous sequence of keys from the beginning of the array.

local t = {1, [100] = 2}
print(#t) is > 1 because t[1] is not nil, but t[1 + 1] is nil.

For an array in which values are stored one after the other, # will return the number of its elements.

Traversing table items

You can only find out how many items are contained in a Lua table by crawling them. The exception is arrays and the # operator to determine the length of the array. Bypass the array using a for loop:

local t = {1, 2, 3, Vanya}
for i = 1, #t, 1 do

— > 1
— > 2
— > 3
— > Vanya

Regular tables are bypassed by a for loop:

local t = {1, 2, x = 4, y = 5, [Pushkin] = "poet"}
for key, value in pairs(t) do
print(key, value)

— > 1 1
— > 2 2
— > y 5
— > x 4
— > Pushkin poet

The order of the items in the table is different from the order in which the values were placed in the table.


An attempt to model object-oriented programming:

local t = {x = 1}

function t:fun()


— > 1

What does this code mean?

  1. Create table t;
  2. It introduced the field x and gave it a value of 1;
  3. A fun function was created in the table;
  4. Inside it, the table was accessed through the variable self (where self is the first hidden parameter in the function. calling a function as t:fun() is similar to calling
  5. Called the fun method in table t;

We created the object, its method, and the call. At the same time, it is not possible to create objects with a certain type. An object and a method exist in the same form. To create an object of type tt that acts in the same way as an object of type t, we need to repeat the code from the beginning.

Is there a solution? Yes. But to do this, you need to study metatables.

local tt = {x = 2}

function tt:fun()

function checkMetod(x)


—> 1
—> 2


Meta tables override the action of built-in types. They are similar to the operator() construct in Cpp. Let's look at how you can add two tables (lua does not have this feature built in).

local data1 = {x = 1}

local data2 = {x = 2}
— create a
table local meta = {}
— define a special field in the table __add (operator +)
function meta.__add(op1, op2)
return op1.x + op2.x

setmetatable(data1, meta)

print(data1 + data2) —> 3

Create two objects, each with an x field, and then create a meta table. In it, we define a function named __add. Finally, a meta table was installed for the first operand.


The table is the fundamental foundation of Lua, embodying almost all of its features.
Because functions are first-class values, table fields can also contain functions. Thus, tables store methods as well.

The implementation of associative arrays in Lua is extremely efficient. The speed of calculating hash functions in Lua is almost flawless. Interpreted Lua scripts cope with this task 2 times slower than programs in the C. And the calculation of functions is much faster than analogues in Perl, Ruby and Python.