Tables
Lua has exactly one data structure, and it does the job of arrays, dictionaries, objects and namespaces all at once.
Array-like
A table literal with no keys builds a sequence, indexed from 1, not 0.
local fruits = { "apple", "banana", "cherry" }
print(fruits[1]) -- apple, indexing starts at 1
print(#fruits) -- 3, the length operator
Dictionary-like
local luak = {
name = "Luak",
version = "5.5.1",
multiplatform = true,
}
print(luak.name) -- dot syntax
print(luak["version"]) -- bracket syntax, same thing
t.key and t["key"] are exactly the same operation. The dot
form is just sugar for a string key.
pairs versus ipairs
ipairs walks the 1..n array part in order and stops at the first
nil. pairs visits every key in the table, array part and
dictionary part alike, in an unspecified order. Use ipairs when you
mean "the list part", pairs when you mean "everything".
for key, value in pairs(luak) do
print(key, value)
end
The length operator has a rule
#t is only well-defined when the array part has no holes, no
nil in the middle of the sequence. A table with a gap has an undefined
length: do not rely on #t for sparse tables, use
table.insert/table.remove to keep the sequence dense
instead of assigning nil into the middle of one.
Nesting
local project = {
name = "Luak",
targets = { "jvm", "native", "js", "wasm" },
org = { name = "Basalt" },
}
print(project.org.name) -- Basalt
print(project.targets[1]) -- jvm
Objects, without a class keyword
A table plus functions that take it as self, the pattern from
Functions, is how Lua does
objects. There is no separate class syntax: metatables extend this further, but
that is beyond an introduction.