Lua Tables
Lua - Tables
Section titled “Lua - Tables”Introduction to Tables
Section titled “Introduction to Tables”Tables are the sole data structuring mechanism in Lua, and they are fundamental to the language. A table is a highly versatile associative array. This means it can be indexed not only by numbers but also by other Lua values like strings, booleans, or even other tables (except nil). Tables are used to represent ordinary arrays, lists, symbol tables (dictionaries/maps), objects, packages, and more.
Tables in Lua are dynamic; their size is not fixed and can grow or shrink as needed. They are often referred to as objects, but it’s important to understand they are distinct from variables that might refer to them.
Creating and Using Tables
Section titled “Creating and Using Tables”An empty table is created using the constructor expression {}.
-- Create an empty tablelocal my_table = {}
-- Assign values using keys (indices)my_table[1] = "Apple" -- Numeric key (array-like)my_table["color"] = "Red" -- String key (dictionary-like)my_table[true] = "Is a fruit" -- Boolean key
-- Access values using keysprint(my_table[1]) -- Output: Appleprint(my_table["color"]) -- Output: Red
-- Alternative syntax for string keys (if valid identifiers)my_table.shape = "Round"print(my_table.shape) -- Output: Round
-- Initialize a table with elementslocal another_table = { name = "Banana", color = "Yellow", peel_status = "Peeled", 10, -- equivalent to [1] = 10 20 -- equivalent to [2] = 20}print(another_table.name) -- Output: Bananaprint(another_table[1]) -- Output: 10Table References and Garbage Collection
Section titled “Table References and Garbage Collection”Variables in Lua do not hold tables themselves, but rather references to tables. When you assign one table variable to another, both variables refer to the same table in memory. Modifying the table through one variable affects the other.
local t1 = { value = 10 }local t2 = t1 -- t2 now refers to the same table as t1
t2.value = 20print(t1.value) -- Output: 20 (since t1 and t2 point to the same table)
t1 = nil -- t1 no longer refers to the table-- The table itself still exists because t2 refers to it.print(t2.value) -- Output: 20
t2 = nil -- Now, no variable refers to the table.-- Lua's garbage collector will eventually reclaim the memory used by the table.Example demonstrating table types and references:
-- Simple empty tablelocal mytable = {}print("Type of mytable is: " .. type(mytable)) -- Type of mytable is: table
mytable[1] = "Lua"mytable["feature"] = "Tables"print("mytable[1] is: " .. mytable[1]) -- mytable[1] is: Luaprint("mytable.feature is: " .. mytable.feature) -- mytable.feature is: Tables
-- alternatetable and mytable refer to the same tablelocal alternatetable = mytable
print("alternatetable[1] is: " .. alternatetable[1]) -- alternatetable[1] is: Luaalternatetable.feature = "Powerful Tables"print("mytable.feature is now: " .. mytable.feature) -- mytable.feature is now: Powerful Tables
-- Release reference from alternatetablealternatetable = nilprint("alternatetable is: " .. tostring(alternatetable)) -- alternatetable is: nil
-- mytable is still accessibleprint("mytable.feature is still: " .. mytable.feature) -- mytable.feature is still: Powerful Tables
mytable = nil -- Now the table is eligible for garbage collectionprint("mytable is: " .. tostring(mytable)) -- mytable is: nilTable Manipulation Functions
Section titled “Table Manipulation Functions”Lua provides a table library with functions for manipulating tables, especially when used as arrays/lists.
| Function Signature | Purpose |
|---|---|
table.concat(list [, sep [, i [, j]]]) | Concatenates the string elements of list (an array-like table) from index i to j. Elements are separated by sep (default is empty string). i defaults to 1, j defaults to #list. |
table.insert(list, [pos,] value) | Inserts value into list at pos. If pos is omitted, inserts at the end. Shifts subsequent elements. |
table.remove(list [, pos]) | Removes the element at pos from list. If pos is omitted, removes the last element. Returns the removed element. Shifts subsequent elements down. |
table.sort(list [, comp]) | Sorts the elements of list in place. An optional comparator function comp(a,b) can be provided, which should return true if a should come before b. |
table.pack(...) | (Lua 5.2+) Returns a new table with all arguments stored into keys 1, 2, etc. and a field ‘n’ with the total number of arguments. |
table.unpack(list [, i [, j]]) | (Lua 5.1 unpack, Lua 5.2+ table.unpack) Returns the elements from the given list from index i to j as separate return values. i defaults to 1, j defaults to #list. |
Note: table.maxn was deprecated in Lua 5.1 and removed in Lua 5.2. To get the length of a sequence-like table (an array without nil holes starting at index 1), use the length operator #.
Examples of Table Manipulation:
Table Concatenation (table.concat)
Section titled “Table Concatenation (table.concat)”local words = {"Lua", "is", "awesome"}print("Concatenated (default): " .. table.concat(words)) -- Luaisawesomeprint("Concatenated with space: " .. table.concat(words, " ")) -- Lua is awesomeprint("Concatenated with dash (subset): " .. table.concat(words, "-", 2, 3)) -- is-awesomeInsert and Remove (table.insert, table.remove, # operator)
Section titled “Insert and Remove (table.insert, table.remove, # operator)”local fruits = {"banana", "orange", "apple"}print("Initial #fruits:", #fruits) -- Initial #fruits: 3
-- Insert at the endtable.insert(fruits, "mango")print("Fruit at index 4:", fruits[4], "(#fruits:", #fruits .. ")") -- Fruit at index 4: mango (#fruits: 4)
-- Insert at a specific positiontable.insert(fruits, 2, "grapes")print("Fruit at index 2:", fruits[2], "(#fruits:", #fruits .. ")") -- Fruit at index 2: grapes (#fruits: 5)-- fruits is now: {"banana", "grapes", "orange", "apple", "mango"}
local removed_fruit = table.remove(fruits) -- Removes last element ("mango")print("Removed last fruit:", removed_fruit, "(#fruits:", #fruits .. ")") -- Removed last fruit: mango (#fruits: 4)-- fruits is now: {"banana", "grapes", "orange", "apple"}
local removed_at_pos = table.remove(fruits, 1) -- Removes first element ("banana")print("Removed fruit at pos 1:", removed_at_pos, "(#fruits:", #fruits .. ")") -- Removed fruit at pos 1: banana (#fruits: 3)-- fruits is now: {"grapes", "orange", "apple"}Sorting Tables (table.sort)
Section titled “Sorting Tables (table.sort)”local numbers = {5, 1, 100, 20, 3}
-- Default sort (ascending)table.sort(numbers)print("Sorted numbers (ascending):")for i, v in ipairs(numbers) do print(string.format(" [%d] = %d", i, v)) end-- Output: [1]=1, [2]=3, [3]=5, [4]=20, [5]=100
-- Custom sort (descending)local names = {"Charlie", "Alice", "Bob"}table.sort(names, function(a, b) return a > b end) -- Sort descendingprint("\nSorted names (descending):")for i, v in ipairs(names) do print(string.format(" [%d] = %s", i, v)) end-- Output: [1]=Charlie, [2]=Bob, [3]=AliceIterating Through Tables
Section titled “Iterating Through Tables”Lua provides two main iterators for tables:
ipairs(t): Iterates over integer keys1, 2, ...(the sequence part) of tabletuntil the firstnilvalue. Ideal for arrays.pairs(t): Iterates over all key-value pairs in tabletin an unspecified order. Use this for dictionary-like tables or when you need to access all elements, including non-sequence parts.
local mixed_table = { [1] = "first", [2] = "second", name = "My Table", [4] = "fourth after nil", -- ipairs will stop before this color = "blue"}mixed_table[3] = "third" -- now sequence is 1,2,3
print("\nIterating with ipairs (sequence part):")for index, value in ipairs(mixed_table) do print(string.format(" Index: %s, Value: %s", tostring(index), tostring(value)))end
print("\nIterating with pairs (all elements):")for key, value in pairs(mixed_table) do print(string.format(" Key: %s, Value: %s", tostring(key), tostring(value)))endFurther Resources: Tables are a vast topic. The official Lua Reference Manual is the definitive source for all details on table behavior, constructors, and the table library.