Claude
Skills
Sign in
Back

Lua Tables Patterns

Included with Lifetime
$97 forever

Use when lua tables as the universal data structure including arrays, dictionaries, objects, metatables, object-oriented patterns, data structures, and advanced table manipulation for building flexible, efficient Lua applications.

General

What this skill does


# Lua Tables Patterns

## Introduction

Tables are Lua's sole compound data structure, serving as arrays, dictionaries,
objects, modules, and more. This versatility makes tables fundamental to Lua
programming, enabling implementations of virtually any data structure through
creative use of table features and metatables.

Tables use associative arrays that can be indexed with any Lua value except nil
and NaN. Array-like tables use consecutive integer indices starting from 1,
while dictionary-like tables use arbitrary keys. Metatables enable operator
overloading and advanced behaviors.

This skill covers table fundamentals, array and dictionary patterns, metatables,
object-oriented programming, common data structures, performance optimization,
and idiomatic table manipulation techniques.

## Table Fundamentals

Tables combine arrays and hash maps into a single versatile data structure with
1-based indexing.

```lua
-- Empty table creation
local t1 = {}
local t2 = table.create(100)  -- Pre-allocate (LuaJIT)

-- Array-style tables (consecutive integers from 1)
local array = {10, 20, 30, 40, 50}
print(array[1])  -- 10
print(array[5])  -- 50
print(#array)    -- 5 (length operator)

-- Dictionary-style tables (any key type)
local dict = {
  name = "Alice",
  age = 30,
  email = "[email protected]"
}

print(dict.name)     -- Dot notation
print(dict["age"])   -- Bracket notation

-- Mixed array and dictionary
local mixed = {
  10, 20, 30,  -- array part: [1]=10, [2]=20, [3]=30
  name = "Bob",
  age = 25
}

print(mixed[2])      -- 20
print(mixed.name)    -- "Bob"

-- Constructor syntax variations
local point = {x = 10, y = 20}
local point2 = {["x"] = 10, ["y"] = 20}  -- Equivalent

-- Nested tables
local nested = {
  user = {
    name = "Charlie",
    address = {
      city = "Seattle",
      zip = "98101"
    }
  }
}

print(nested.user.address.city)  -- "Seattle"

-- Table insertion and removal
local list = {}
table.insert(list, "first")
table.insert(list, "second")
table.insert(list, 2, "middle")  -- Insert at position 2

print(list[1])  -- "first"
print(list[2])  -- "middle"
print(list[3])  -- "second"

local removed = table.remove(list, 2)  -- Remove at position 2
print(removed)  -- "middle"

-- Table iteration
-- Pairs: All keys (unordered)
for key, value in pairs(dict) do
  print(key, value)
end

-- Ipairs: Integer keys in order (1, 2, 3, ...)
for index, value in ipairs(array) do
  print(index, value)
end

-- Manual iteration
for i = 1, #array do
  print(i, array[i])
end

-- Table copying (shallow)
local original = {1, 2, 3, x = 10}
local copy = {}
for k, v in pairs(original) do
  copy[k] = v
end

-- Table concatenation
local fruits = {"apple", "banana", "cherry"}
local str = table.concat(fruits, ", ")
print(str)  -- "apple, banana, cherry"

-- Sorting
local numbers = {5, 2, 8, 1, 9}
table.sort(numbers)
-- numbers is now {1, 2, 5, 8, 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)
```

Tables efficiently combine arrays and hash tables, with the implementation
automatically optimizing storage based on usage patterns.

## Array Patterns

Lua arrays use 1-based indexing and provide efficient sequential access through
the array part of tables.

```lua
-- Creating arrays
local empty = {}
local numbers = {10, 20, 30, 40, 50}
local strings = {"hello", "world", "lua"}

-- Array length
print(#numbers)  -- 5

-- Appending elements
numbers[#numbers + 1] = 60
table.insert(numbers, 70)

-- Prepending (expensive)
table.insert(numbers, 1, 0)

-- Removing elements
local last = table.remove(numbers)  -- Remove and return last
local first = table.remove(numbers, 1)  -- Remove and return first

-- Array operations
function map(array, fn)
  local result = {}
  for i = 1, #array do
    result[i] = fn(array[i])
  end
  return result
end

local doubled = map(numbers, function(x) return x * 2 end)

function filter(array, predicate)
  local result = {}
  for i = 1, #array do
    if predicate(array[i]) then
      table.insert(result, array[i])
    end
  end
  return result
end

local evens = filter(numbers, function(x) return x % 2 == 0 end)

function reduce(array, fn, initial)
  local accumulator = initial
  for i = 1, #array do
    accumulator = fn(accumulator, array[i])
  end
  return accumulator
end

local sum = reduce(numbers, function(acc, x) return acc + x end, 0)

-- Array slicing
function slice(array, start_idx, end_idx)
  local result = {}
  end_idx = end_idx or #array
  for i = start_idx, end_idx do
    table.insert(result, array[i])
  end
  return result
end

local subset = slice(numbers, 2, 4)

-- Array reversal
function reverse(array)
  local result = {}
  for i = #array, 1, -1 do
    table.insert(result, array[i])
  end
  return result
end

-- In-place reversal
function reverse_in_place(array)
  local n = #array
  for i = 1, math.floor(n / 2) do
    array[i], array[n - i + 1] = array[n - i + 1], array[i]
  end
end

-- Array flattening
function flatten(array)
  local result = {}
  for i = 1, #array do
    if type(array[i]) == "table" then
      local nested = flatten(array[i])
      for j = 1, #nested do
        table.insert(result, nested[j])
      end
    else
      table.insert(result, array[i])
    end
  end
  return result
end

local nested = {1, {2, 3}, {4, {5, 6}}}
local flat = flatten(nested)  -- {1, 2, 3, 4, 5, 6}

-- Array chunking
function chunk(array, size)
  local result = {}
  for i = 1, #array, size do
    local chunk = {}
    for j = i, math.min(i + size - 1, #array) do
      table.insert(chunk, array[j])
    end
    table.insert(result, chunk)
  end
  return result
end

local chunked = chunk({1, 2, 3, 4, 5, 6, 7}, 3)
-- {{1, 2, 3}, {4, 5, 6}, {7}}

-- Unique values
function unique(array)
  local seen = {}
  local result = {}
  for i = 1, #array do
    if not seen[array[i]] then
      seen[array[i]] = true
      table.insert(result, array[i])
    end
  end
  return result
end

-- Array intersection
function intersection(a, b)
  local set = {}
  for i = 1, #a do
    set[a[i]] = true
  end

  local result = {}
  for i = 1, #b do
    if set[b[i]] then
      table.insert(result, b[i])
    end
  end
  return result
end
```

Use arrays for sequential data with numeric indices, leveraging Lua's
optimizations for consecutive integer keys.

## Dictionary and Set Patterns

Dictionary tables use arbitrary keys for fast lookups, while sets use keys with
true values.

```lua
-- Dictionary creation
local user = {
  id = 1,
  name = "Alice",
  email = "[email protected]",
  age = 30
}

-- Dynamic key access
local key = "name"
print(user[key])  -- "Alice"

-- Adding and modifying
user.city = "Seattle"
user.age = 31

-- Removing keys
user.age = nil

-- Checking key existence
if user.name then
  print("Name exists")
end

-- Counting keys
function table_length(t)
  local count = 0
  for _ in pairs(t) do
    count = count + 1
  end
  return count
end

print(table_length(user))

-- Merging dictionaries
function merge(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

-- Deep copy
function deep_copy(obj)
  if type(obj) ~= 'table' then return obj end
  local copy = {}
  for k, v in pairs(obj) do
    copy[deep_copy(k)] = deep_copy(v)
  end
  return setmetatable(copy, getmetatable(obj))
end

-- Set implementation
local Set = {}

function Set.new(list)
  local set = {}
  for i = 1, #list do
    set[list[i]] = true
  end
  return set
end

function Set.add(set, value)
  set[value] = true
end

function Set.remove(set, value)
  set[value] = nil
end

function Set.contains(set, value)
  return set[value] == true
end

function Set.union(a, b)
  local result = {}
  for k in pairs(a) do result[k] = true end
  for k in pairs(b) do result[k] = true end
  return result
end

function Set.intersection(a, b)
  local result = {}
  for k in pairs(a) do

Related in General