Lua Tables Basic Usage


Basic table usage includes accessing and assigning table elements, adding table content, and removing table content. These examples assume you know how to create tables.

Accessing Elements

Given the following table,

local example_table = {"Nausea", "Heartburn", "Indigestion", "Upset Stomach",
                       "Diarrhea", cure = "Pepto Bismol"}

One can index the sequential part of the table by using the index syntax, the argument to the index syntax being the key of the desired key-value pair. As explained in the creation tutorial, most of the declaration syntax is syntactic sugar for declaring key-value pairs. Sequentially included elements, like the first five values in example_table, use increasing integer values as keys; the record syntax uses the name of the field as a string.

print(example_table[2])        --> Heartburn
print(example_table["cure"])   --> Pepto Bismol

For string keys there is syntax sugar to parallel the record-style syntax for string keys in table creation. The following two lines are equivalent.

print(example_table.cure)      --> Pepto Bismol
print(example_table["cure"])   --> Pepto Bismol

You can access tables using keys that you haven't used before, that is not an error as it in other languages. Doing so returns the default value nil.

Assigning Elements

You can modify existing table elements by assigning to a table using the index syntax. Additionally, the record-style indexing syntax is available for setting values as well

example_table.cure = "Lots of water, the toilet, and time"
print(example_table.cure)    --> Lots of water, the toilet, and time

example_table[2] = "Constipation"
print(example_table[2])      --> Constipation

You can also add new elements to an existing table using assignment.

example_table.copyright_holder = "Procter & Gamble"
example_table[100] = "Emergency source of water"

Special Remark: Some strings are not supported with the record-syntax. See the remarks section for details.

Removing Elements

As stated previously, the default value for a key with no assigned value is nil. Removing an element from a table is as simple as resetting the value of a key back to the default value.

example_table[100] = "Face Mask"

The elements is now indistinguishable from an unset element.

Table Length

Tables are simply associative arrays (see remarks), but when contiguous integer keys are used starting from 1 the table is said to have a sequence.

Finding the length of the sequence part of a table is done using #:

local example_table = {'a', 'l', 'p', 'h', 'a', 'b', 'e', 't'}
print(#example_table)    --> 8

You can use the length operation to easily append items to a sequence table.

example_table[#example_table+1] = 'a'
print(#example_table)    --> 9

In the above example, the previous value of #example_table is 8, adding 1 gives you the next valid integer key in the sequence, 9, so... example_table[9] = 'a'. This works for any length of table.

Special Remark: Using integer keys that aren't contiguous and starting from 1 breaks the sequence making the table into a sparse table. The result of the length operation is undefined in that case. See the remarks section.

Using Table Library Functions to Add/Remove Elements

Another way to add elements to a table is the table.insert() function. The insert function only works on sequence tables. There are two ways to call the function. The first example shows the first usage, where one specifies the index to insert the element (the second argument). This pushes all elements from the given index to #table up one position. The second example shows the other usage of table.insert(), where the index isn't specified and the given value is appended to the end of the table (index #table + 1).

local t = {"a", "b", "d", "e"}
table.insert(t, 3, "c")        --> t = {"a", "b", "c", "d", "e"}

t = {"a", "b", "c", "d"}
table.insert(t, "e")           --> t = {"a", "b", "c", "d", "e"}

To parallel table.insert() for removing elements is table.remove(). Similarly it has two calling semantics: one for removing elements at a given position, and another for removing from the end of the sequence. When removing from the middle of a sequence, all following elements are shifted down one index.

local t = {"a", "b", "c", "d", "e"}
local r = table.remove(t, 3)       --> t = {"a", "b", "d", "e"}, r = "c"

t = {"a", "b", "c", "d", "e"}
r = table.remove(t)                --> t = {"a", "b", "c", "d"}, r = "e"

These two functions mutate the given table. As you might be able to tell the second method of calling table.insert() and table.remove() provides stack semantics to tables. Leveraging that, you can write code like the example below.

function shuffle(t)
    for i = 0, #t-1 do
        table.insert(t, table.remove(t, math.random(#t-i)))

It implements the Fisher-Yates Shuffle, perhaps inefficiently. It uses the table.insert() to append the randomly extracted element onto the end of same table, and the table.remove() to randomly extract an element from the remaining unshuffled portion of the table.