Lua Tables

Table as Array

Sequence (integer-indexed) tables
-- Arrays are 1-indexed in Lua
local ports = { 22, 80, 443, 8080 }
print(ports[1])              -- 22 (first element)
print(#ports)                -- 4 (length)

-- Append
table.insert(ports, 9090)    -- append to end
ports[#ports + 1] = 3000     -- manual append (faster)

-- Insert at position
table.insert(ports, 2, 21)   -- insert 21 at index 2

-- Remove
table.remove(ports, 1)       -- remove first, shift down
table.remove(ports)          -- remove last (pop)

-- Iterate in order
for i, port in ipairs(ports) do
  print(i, port)
end
Table operations
-- Sort
local hosts = { "vault-01", "bind-01", "ise-01" }
table.sort(hosts)                        -- alphabetical in-place
table.sort(hosts, function(a, b)
  return #a < #b                         -- sort by length
end)

-- Concat (join)
table.concat(hosts, ", ")               -- "bind-01, ise-01, vault-01"
table.concat(ports, ":")                -- "22:80:443"

-- Unpack
local a, b, c = table.unpack(ports)     -- destructure
print(table.unpack({ 1, 2, 3 }))        -- 1  2  3

Table as Dictionary

Key-value (hash) tables
local device = {
  hostname = "sw-core-01",
  ip       = "10.50.1.2",
  vlans    = { 10, 20, 30 },
  status   = "active",
}

-- Access
print(device.hostname)                   -- dot syntax
print(device["hostname"])                -- bracket syntax (required for dynamic keys)

-- Set
device.location = "rack-A3"
device["model"] = "C9300"

-- Delete
device.location = nil

-- Check existence
if device.hostname then
  print("hostname exists")
end

-- Iterate (unordered)
for key, val in pairs(device) do
  print(key .. " = " .. tostring(val))
end

Nested Tables

Complex data structures
local inventory = {
  switches = {
    { hostname = "sw-core-01", ip = "10.50.1.2", vlans = { 10, 20 } },
    { hostname = "sw-access-01", ip = "10.50.1.3", vlans = { 10 } },
  },
  routers = {
    { hostname = "rtr-gw-01", ip = "10.50.1.1" },
  },
}

-- Access nested
print(inventory.switches[1].hostname)    -- "sw-core-01"
print(inventory.switches[1].vlans[2])    -- 20

-- Safe nested access (guard against nil)
local vlan = inventory.switches
  and inventory.switches[1]
  and inventory.switches[1].vlans
  and inventory.switches[1].vlans[1]

Table Patterns

Common idioms
-- Table as set
local allowed = { [22] = true, [80] = true, [443] = true }
if allowed[port] then
  print("allowed")
end

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

-- Count entries (# only works for sequences)
local function table_length(t)
  local count = 0
  for _ in pairs(t) do count = count + 1 end
  return count
end

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

-- Filter
local function filter(t, pred)
  local result = {}
  for i, v in ipairs(t) do
    if pred(v) then result[#result + 1] = v end
  end
  return result
end

local high_ports = filter(ports, function(p) return p > 1023 end)