Lua Tables Patterns
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.
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) doRelated in General
modeling-omnistudio-epc-catalog
IncludedSalesforce Industries CME EPC product-modeling skill for Product2-based catalog creation. Use when creating EPC products, configuring product attributes, building offer bundles with Product Child Items, or reviewing EPC DataPack JSON metadata for product catalog changes. TRIGGER when: user creates or updates Product2 EPC records, AttributeAssignment payloads, AttributeMetadata/AttributeDefaultValues, Offer bundles, or ProductChildItem relationships. DO NOT TRIGGER when: designing OmniScripts/FlexCards/Integration Procedures (use building-omnistudio-omniscript, building-omnistudio-flexcard, or building-omnistudio-integration-procedure), implementing Apex business logic (use generating-apex), or troubleshooting deployment pipelines (use deploying-metadata).
relationship-science-coach
IncludedUse this skill for direct, practical adult relationship coaching: couples conflict, repair, trust, marriage, dating, flirting, attachment patterns, emotional connection, sex, desire differences, eroticism, kink negotiation, affection, love languages, breakups, and long-term passion. Draw on Gottman, EFT and Hold Me Tight, attachment science, modern sex research, Perel, Nagoski, Kerner, Schnarch, Love and Stosny, and flexible love-language tools. Be concrete and low-hedge. Redirect only for imminent danger, abuse, coercive control, minors, non-consent, self-harm, stalking, or medical/legal/psychiatric decisions.
building-sf-integrations
IncludedSalesforce integration architecture and runtime plumbing with 120-point scoring. Use this skill to set up Named Credentials, External Credentials, External Services, REST/SOAP callout patterns, Platform Events, and Change Data Capture. TRIGGER when: user sets up Named Credentials, External Services, REST/SOAP callouts, Platform Events, CDC, or touches .namedCredential-meta.xml files. DO NOT TRIGGER when: Connected App/OAuth config (use configuring-connected-apps), Apex-only logic (use generating-apex), or data import/export (use handling-sf-data).
venue-templates
IncludedAccess comprehensive LaTeX templates, formatting requirements, and submission guidelines for major scientific publication venues (Nature, Science, PLOS, IEEE, ACM), academic conferences (NeurIPS, ICML, CVPR, CHI), research posters, and grant proposals (NSF, NIH, DOE, DARPA). This skill should be used when preparing manuscripts for journal submission, conference papers, research posters, or grant proposals and need venue-specific formatting requirements and templates.
let-fate-decide
IncludedDraws the 12 Houses of the Zodiac Tarot spread to inject entropy into planning when prompts are vague, ambiguous, or casually delegated. Interprets the spread to guide next steps. Use when the user says 'let fate decide', 'YOLO', 'whatever', 'idk', or other nonchalant phrases, makes Yu-Gi-Oh references, or when you are about to arbitrarily pick between multiple reasonable approaches. Prefer over ask-questions-if-underspecified when the user's tone is casual or playful rather than precision-seeking.
net-ops
IncludedCross-platform network troubleshooting (Windows, macOS, Linux) via local or remote shell. Use for: DNS broken, can't resolve hostnames, nslookup/dig works but apps fail, NRPT, WFP, scutil, /etc/resolver, systemd-resolved, /etc/resolv.conf, NetworkManager, VPN DNS leak residue (ProtonVPN/Mullvad/WireGuard/AnyConnect), AV/firewall blocking DNS or DoH, Tailscale DNS interaction, intermittent connectivity, remote diagnostics over SSH.