Tables in Lua
Tables are Lua’s only data structure, and they’re incredibly versatile. Tables can be used as arrays, dictionaries, objects, and more. Understanding tables is essential for effective Lua programming.
Creating Tables
Tables are created using curly braces {}:
-- Empty table
local empty_table = {}
-- Table with initial values
local fruits = {"apple", "banana", "orange"}
local person = {name = "Alice", age = 30}Arrays (Numeric Index)
Tables with consecutive numeric keys act as arrays:
local colors = {"red", "green", "blue"}
-- Access by index (Lua arrays are 1-indexed)
print(colors[1]) -- red
print(colors[2]) -- green
print(colors[3]) -- blue
-- Add new element
colors[4] = "yellow"
print(colors[4]) -- yellow
-- Get array length
print(#colors) -- 4Array Operations
local numbers = {10, 20, 30, 40, 50}
-- Iterate over array
for i, value in ipairs(numbers) do
print(i, value)
end
-- Add to end
table.insert(numbers, 60)
print(#numbers) -- 6
-- Remove from end
local removed = table.remove(numbers)
print(removed) -- 60
print(#numbers) -- 5
-- Insert at specific position
table.insert(numbers, 3, 25) -- Insert 25 at position 3
-- numbers is now: {10, 20, 25, 30, 40, 50}
-- Remove at specific position
table.remove(numbers, 2) -- Remove element at position 2
-- numbers is now: {10, 25, 30, 40, 50}Dictionaries (Key-Value Pairs)
Tables with string keys act as dictionaries:
local person = {
name = "Alice",
age = 30,
city = "New York"
}
-- Access values
print(person.name) -- Alice
print(person["age"]) -- 30
-- Modify values
person.age = 31
person.city = "Boston"
-- Add new key-value pairs
person.job = "Engineer"
-- Iterate over dictionary
for key, value in pairs(person) do
print(key, ":", value)
endDynamic Key Names
local data = {}
-- Using variables as keys
local key1 = "username"
local key2 = "score"
data[key1] = "john_doe"
data[key2] = 1500
print(data.username) -- john_doe
print(data.score) -- 1500
-- Keys can be any type except nil
local mixed_keys = {
[1] = "numeric key",
["string"] = "string key",
[true] = "boolean key"
}
for key, value in pairs(mixed_keys) do
print(type(key), key, ":", value)
endMixed Tables
Tables can contain both array and dictionary elements:
local mixed = {
"first", -- array element [1]
"second", -- array element [2]
name = "Test", -- dictionary element
"third", -- array element [3] (because nil name doesn't count as array)
age = 25 -- dictionary element
}
-- Array part
for i, value in ipairs(mixed) do
print("Array", i, ":", value)
end
-- Dictionary part
for key, value in pairs(mixed) do
if type(key) == "string" then
print("Dict", key, ":", value)
end
endTable Operations
Table Manipulation Functions
local numbers = {3, 1, 4, 1, 5, 9, 2, 6}
-- Sort array
table.sort(numbers)
print(table.concat(numbers, ", ")) -- 1, 1, 2, 3, 4, 5, 6, 9
-- Custom sort
local people = {
{name = "Alice", age = 30},
{name = "Bob", age = 25},
{name = "Charlie", age = 35}
}
table.sort(people, function(a, b)
return a.age < b.age
end)
for i, person in ipairs(people) do
print(i, person.name, person.age)
end
-- 1 Bob 25
-- 2 Alice 30
-- 3 Charlie 35Checking for Elements
function table_contains(table, element)
for _, value in pairs(table) do
if value == element then
return true
end
end
return false
end
local fruits = {"apple", "banana", "orange"}
print(table_contains(fruits, "banana")) -- true
print(table_contains(fruits, "grape")) -- falseMerging Tables
function merge_tables(t1, t2)
local result = {}
for k, v in pairs(t1) do result[k] = v end
for k, v in pairs(t2) do result[k] = v end
return result
end
local defaults = {color = "blue", size = "medium"}
local settings = {size = "large", style = "bold"}
local merged = merge_tables(defaults, settings)
for k, v in pairs(merged) do
print(k, v)
end
-- color blue
-- size large (overwrites default)
-- style boldAdvanced Table Usage
Objects and Methods
-- Object-like table with methods
local counter = {
value = 0,
increment = function(self)
self.value = self.value + 1
end,
get_value = function(self)
return self.value
end,
reset = function(self)
self.value = 0
end
}
counter:increment()
counter:increment()
print(counter:get_value()) -- 2
counter:reset()
print(counter:get_value()) -- 0Metatables (Advanced)
-- Create a table with custom behavior
local vector = {
x = 0,
y = 0
}
local vector_metatable = {
__add = function(a, b)
return {
x = a.x + b.x,
y = a.y + b.y
}
end,
__tostring = function(v)
return "(" .. v.x .. ", " .. v.y .. ")"
end
}
setmetatable(vector, vector_metatable)
-- Create vectors
local v1 = {x = 1, y = 2}
local v2 = {x = 3, y = 4}
setmetatable(v1, vector_metatable)
setmetatable(v2, vector_metatable)
local v3 = v1 + v2
print(tostring(v3)) -- (4, 6)Practical Examples
Configuration Table
local config = {
database = {
host = "localhost",
port = 5432,
name = "myapp"
},
server = {
port = 8080,
host = "0.0.0.0"
},
features = {
authentication = true,
logging = true,
debug = false
}
}
-- Access nested configuration
print(config.database.host) -- localhost
print(config.server.port) -- 8080
print(config.features.auth) -- trueData Processing Pipeline
local users = {
{id = 1, name = "Alice", score = 85},
{id = 2, name = "Bob", score = 92},
{id = 3, name = "Charlie", score = 78},
{id = 4, name = "Diana", score = 95}
}
-- Filter high scorers
local high_scorers = {}
for _, user in ipairs(users) do
if user.score >= 90 then
table.insert(high_scorers, user)
end
end
-- Sort by score
table.sort(high_scorers, function(a, b)
return a.score > b.score
end)
-- Display results
for i, user in ipairs(high_scorers) do
print(i, user.name, user.score)
end
-- 1 Diana 95
-- 2 Bob 92Simple Cache System
local cache = {
data = {},
get = function(self, key)
return self.data[key]
end,
set = function(self, key, value)
self.data[key] = value
end,
has = function(self, key)
return self.data[key] ~= nil
end
}
-- Usage
cache:set("user:1", {name = "Alice", age = 30})
print(cache:has("user:1")) -- true
local user = cache:get("user:1")
print(user.name) -- AliceBest Practices
- Use appropriate data structures (arrays vs dictionaries)
- Keep tables simple when possible
- Use meaningful keys and consistent naming
- Consider performance for large tables
- Use
ipairsfor arrays andpairsfor dictionaries - Initialize tables properly before use
Next Steps
Now that you understand tables, learn about strings to work with text data effectively.
For more table details, see the Lua manual.
Last updated on