Tables in Depth

11.1 Sequences and the Length Operator

A sequence is a table whose positive integer keys are exactly 1..n with no holes. #t is only reliable for sequences.

local t = {1, 2, nil, 4}
print(#t)          -- 4 or 2: undefined for tables with holes ("border")!
local safe = table.pack(1, nil, 3)
print(safe.n)      --> 3 (track counts explicitly when nils are possible)

11.2 Array and Hash Parts

Internally, tables have an array part (dense integer keys) and a hash part. Lua manages both automatically. Preallocating with constructors ({0, 0, 0}) is faster than growing (Lua 5.4 has no public table.new; LuaJIT does: require("table.new")).

11.3 Common Table Operations

-- Copy (shallow)
local function shallow_copy(t)
    local copy = {}
    for k, v in pairs(t) do copy[k] = v end
    return copy
end

-- Deep copy (handles nested tables and cycles)
local function deep_copy(orig, seen)
    if type(orig) ~= "table" then return orig end
    seen = seen or {}
    if seen[orig] then return seen[orig] end
    local copy = {}
    seen[orig] = copy
    for k, v in pairs(orig) do copy[deep_copy(k, seen)] = deep_copy(v, seen) end
    return setmetatable(copy, getmetatable(orig))
end

-- Count keys (# doesn't work for dictionaries)
local function count(t) local n = 0 for _ in pairs(t) do n = n + 1 end return n end

-- Check whether a table is empty
local function is_empty(t) return next(t) == nil end

-- Merge
local function merge(a, b)
    local r = shallow_copy(a)
    for k, v in pairs(b) do r[k] = v end
    return r
end

-- Keys and values as lists
local function keys(t) local r = {} for k in pairs(t) do r[#r + 1] = k end return r end

-- Reverse a sequence in place
local function reverse(t)
    local i, j = 1, #t
    while i < j do t[i], t[j] = t[j], t[i]; i, j = i + 1, j - 1 end
    return t
end

-- Slice
local function slice(t, i, j) return {table.unpa
…

11.4 Sets and Lookup Tables

local function Set(list)
    local s = {}
    for _, v in ipairs(list) do s[v] = true end
    return s
end
local keywords = Set{"if", "then", "else", "end"}
print(keywords["if"], keywords["foo"])     --> true  nil