Tables are collections of entries with keys and values. They are the only aggregate data structure provided. All other data structures (arrays, lists, sets, and so on) are built from tables. Table keys and values can be any type, including other tables. Keys and values within the same table can mix types.

  • Table Constructors
  • Table Usage
  • Tables as Arrays
  • Tables as Records

Table constructors

Table constructors allow you to specify a table with keys and associated values. The syntax is:

{[key1] = value1, [key2] = value2, …}

where the keys and values are expressions. If the keys are strings that are not reserved words, the brackets and quotes around the keys can be omitted. Example:

{key1 = “value1”, key2 = “value2”, key3 = “value3”}

An empty table is specified simply by {}.

A table constructor may be used in an assignment to set a variable to refer to a table. Examples:

local t1 = {} – set t1 to an empty table local t2 = {key1 = “value1”, key2 = “value2”, key3 = “value3”}

Note that tables themselves are anonymous. More than one variable may refer to the same table. Continuing the above example:

local t3 = t2 – both t2 and t3 refer to the same table

Table usage

As you would expect, you can use keys to find values in a table. The syntax is table[key], where table is a table reference (typically a variable assigned a table), and key is an expression providing the key. If this is used in an expression and the key exists in the table, this returns the value associated with the key. If the key is not in the table, this returns nil. If this is used as the variable in an assignment, and the key does not exist in the table, it creates a new entry for the key and value. If the key already exists in the table, it replaces the key’s value with the new value. Examples:

local t = {} – sets t to an empty table t[“k1”] = “v1” – creates an entry for key “k1” and value “v1” v1 = t[“k1”] – sets v1 to the value for key “k1” = “v1” t[“k1”] = “new_v1” – sets the value for key “k1” to “new_v1”

Table as arrays

The traditional array can be implemented using a table with integer keys as indices. An array can have any indices, including negative ones, but the convention is to start arrays at index 1 (not 0 as is the case with languages like C and Java). There is a special purpose table constructor for such arrays:

{value1, value2, value3, … }

Array references are then array[index].

The length operator # returns the number of elements in an array with consecutive indices starting at 1. Example:

local a = {“value1”, “value2”, “value3”} local length = #a – sets length to the length of array a = 3

Arrays can be sparse, where only the defined elements are allocated. But # cannot be used on a sparse array with non-consecutive indices. Example:

local sparse_array = {} – set up an empty array sparse_array[1] = “value1” – add an element at index 1 sparse_array[99] = “value99” – add an element at index 99

Multidimensional arrays can be set up as tables of tables. For example, a 3x3 matrix could be set up by:

local m = {{1, 2, 3}, {4, 5, 6}, {7, 8, 9} } local v22 = m[2][2] – sets v22 to 5

Tables as records

Records with fields can be implemented as tables with field name keys. The reference form table.field can be used for table[“field”]. Examples:

local person = {name = “John Smith”, phone = “777-777-7777”} local name = – sets name to “John Smith”

An array of tables can be used for a sequence of records. Example:

local people = { {name = “John Smith”, phone = “777-777-7777”}, {name = “Jane Doe”, phone = “888-888-8888”} … }

name = people[2].name – sets name to “Jane Doe”