Вложенные таблицы и структурированные данные
Создавайте вложенные структуры и обращайтесь к полям на разных уровнях вложенности.
«Вложенные таблицы и структурированные данные» — бесплатный урок Lua Academy на CoddyKit. Это урок 4 из 4. Ты можешь прочитать весь урок бесплатно ниже — а потом практиковать его прямо в браузере с встроенным редактором кода и ИИ-репетитором 24/7. Это часть пути обучения Lua Academy, и твой прогресс синхронизируется между веб-версией и приложением CoddyKit. Курс Lua Academy содержит 4 уроков всего.
Основы вложенных таблиц
Таблицы могут содержать другие таблицы в качестве значений, создавая структуры произвольной глубины. Обращайтесь к вложенным полям, последовательно используя точки или скобки. Отсутствующие промежуточные таблицы вызывают ошибки — всегда проверяйте, что родительские таблицы существуют, прежде чем обращаться к глубоким полям.
local company = {
name = "CoddyKit",
address = {
city = "Istanbul",
country = "Turkey",
zip = "34000"
},
employees = 25
}
print(company.name) -- CoddyKit
print(company.address.city) -- Istanbul
print(company["address"]["zip"]) -- 34000Безопасный доступ к вложенным полям
Обращение к полю значения nil приводит к сбою с ошибкой «attempt to index a nil value». Защититесь от этого с помощью короткого замыкания оператора and: t and t.a and t.a.b. В некоторых проектах определяют вспомогательную функцию get(t, ...), которая безопасно проходит по цепочке ключей.
local function get(t, ...)
local cur = t
for _, key in ipairs({...}) do
if type(cur) ~= "table" then return nil end
cur = cur[key]
end
return cur
end
local data = {user = {profile = {age = 30}}}
print(get(data, "user", "profile", "age")) -- 30
print(get(data, "user", "missing", "field")) -- nilМассив записей
Распространённый шаблон — массив таблиц (записей). Каждый элемент представляет собой таблицу с именованными полями. Выполняйте перебор с помощью ipairs и обращайтесь к полям по имени. Это аналог массива объектов или списка структур в Lua.
local users = {
{id=1, name="Alice", score=95},
{id=2, name="Bob", score=87},
{id=3, name="Carol", score=91},
}
for _, user in ipairs(users) do
print(user.id, user.name, user.score)
endДинамическое построение вложенных таблиц
Создавайте вложенные структуры поэтапно, формируя внутренние таблицы по мере необходимости. Всегда инициализируйте таблицу перед добавлением в неё элементов. Распространённая ошибка — забыть создать внутреннюю таблицу, а затем попытаться обратиться к nil по индексу.
local tree = {}
tree.root = {value = 10}
tree.root.left = {value = 5}
tree.root.right = {value = 15}
tree.root.left.left = {value = 2}
print(tree.root.value) -- 10
print(tree.root.left.value) -- 5
print(tree.root.left.left.value) -- 2Таблица как конфигурация в стиле JSON
Таблицы Lua часто используют для конфигурационных файлов, подобно JSON или YAML. Файл возвращает таблицу, а приложение загружает её с помощью dofile() или require(). Вложенные таблицы представляют вложенные разделы конфигурации.
-- config.lua (returned table)
local config = {
server = {
host = "0.0.0.0",
port = 8080,
ssl = false,
},
db = {
host = "localhost",
name = "appdb",
pool_size = 10,
},
logging = { level = "info", file = "/var/log/app.log" }
}
print(config.server.port) -- 8080
print(config.db.pool_size) -- 10Граф в виде списка смежности
Представьте граф в виде таблицы таблиц: каждый ключ — это узел, а его значение — список соседей. Такое представление в виде списка смежности экономно расходует память для разреженных графов и удобно для работы в Lua.
local graph = {
A = {"B", "C"},
B = {"A", "D"},
C = {"A", "D"},
D = {"B", "C"},
}
-- BFS from A
local visited = {A=true}
local queue = {"A"}
while #queue > 0 do
local node = table.remove(queue, 1)
io.write(node .. " ")
for _, neighbor in ipairs(graph[node]) do
if not visited[neighbor] then
visited[neighbor] = true
queue[#queue+1] = neighbor
end
end
end
print() -- A B C DИзменение вложенных полей
Изменяйте вложенные поля, обращаясь к родительской таблице и присваивая значение ключу. Поскольку таблицы передаются по ссылке, любая функция, получившая таблицу, может изменить её содержимое на месте — вызывающая сторона увидит эти изменения.
local player = {name="Hero", stats={hp=100, mp=50, atk=20}}
local function takeDamage(p, dmg)
p.stats.hp = math.max(0, p.stats.hp - dmg)
end
takeDamage(player, 35)
print(player.stats.hp) -- 65
player.stats.atk = player.stats.atk + 5
print(player.stats.atk) -- 25Сериализация вложенных таблиц
Преобразование вложенной таблицы в строку полезно для отладки или журналирования. Простой рекурсивный сериализатор обрабатывает вложенность любой глубины, но не умеет работать с циклами (циклическими ссылками).
local function serialize(val, indent)
indent = indent or 0
local pad = string.rep(" ", indent)
if type(val) ~= "table" then
return tostring(val)
end
local parts = {"{"}
for k, v in pairs(val) do
parts[#parts+1] = pad.." "..tostring(k).."="..serialize(v,indent+1)
end
parts[#parts+1] = pad.."}"
return table.concat(parts, "\n")
end
local data = {x=1, nested={y=2, z=3}}
print(serialize(data))Разреженные матрицы
Наивное хранение двумерной матрицы приводит к перерасходу памяти для больших разреженных входных данных. Храните только ненулевые элементы во вложенной таблице: matrix[row][col] = value. Так можно эффективно представлять огромные матрицы, если большинство значений равно нулю.
local function newMatrix()
return setmetatable({}, {__index=function(t,k)
local row = {}
rawset(t, k, row)
return row
end})
end
local m = newMatrix()
m[1][1] = 5
m[3][7] = 12
m[100][200] = 99
print(m[1][1]) -- 5
print(m[3][7]) -- 12
print(m[2][5]) -- nil (sparse: no value)Проверка глубокой эквивалентности
Таблицы сравниваются по ссылке с помощью ==, а не по значению. Чтобы структурно сравнить вложенные таблицы, напишите рекурсивную функцию сравнения, которая сопоставляет каждую пару «ключ–значение» и рекурсивно обрабатывает вложенные таблицы.
local function deepEqual(a, b)
if type(a) ~= type(b) then return false end
if type(a) ~= "table" then return a == b end
for k, v in pairs(a) do
if not deepEqual(v, b[k]) then return false end
end
for k in pairs(b) do
if a[k] == nil then return false end
end
return true
end
print(deepEqual({1,{2,3}},{1,{2,3}})) -- true
print(deepEqual({1,{2,3}},{1,{2,4}})) -- falseБыстрая проверка
Что происходит при обращении к t.a.b, если t.a равно nil?
Итоги: вложенные таблицы
Краткое содержание:
- Таблицы можно вкладывать на любую глубину:
t.a.b.c - Защищайте глубокий доступ:
t and t.a and t.a.b - Таблицы — ссылочные типы, поэтому функции изменяют их на месте
- Массив записей:
{{name=...},{name=...}} - Разреженная матрица: вложенные таблицы для экономии памяти
- Для глубокой эквивалентности требуется рекурсивное сравнение
Изучай Lua с ИИ-репетитором — бесплатно
Пиши и запускай код прямо в браузере, получай мгновенную помощь от ИИ-репетитора 24/7 и продолжи учиться на сайте или в приложении.
- Курсы
- 40
- Уроки
- 159
Часто задаваемые вопросы
Урок «Вложенные таблицы и структурированные данные» бесплатный?
Да — полный текст урока «Вложенные таблицы и структурированные данные» бесплатно доступен здесь в веб-версии. Чтобы практиковать его интерактивно (встроенный редактор кода и ИИ-репетитор 24/7) и разблокировать остальной курс Lua Academy, подпишись на CoddyKit PRO. Курс Lua Academy содержит 4 уроков всего.
Чему я научусь в уроке «Вложенные таблицы и структурированные данные»?
Создавайте вложенные структуры и обращайтесь к полям на разных уровнях вложенности. Ты практикуешь Lua Academy с помощью реального кода, который запускаешь прямо в браузере, и ИИ-репетитор 24/7 отвечает на твои вопросы во время урока.
Нужен ли мне опыт, чтобы начать Lua Academy?
Предыдущий опыт не требуется. Lua Academy на CoddyKit структурирован для всех уровней — от новичков до продвинутых, поэтому ты можешь начать отсюда или с самого начала и учиться в своем темпе. Это урок 4 из 4.
Сколько времени занимает урок «Вложенные таблицы и структурированные данные»?
Большинство уроков CoddyKit занимают около 5–10 минут. Каждый из них компактный и интерактивный, поэтому ты постоянно делаешь прогресс и продолжаешь с того же места в веб-версии и приложении.
Можно ли писать и запускать код в этом уроке Lua Academy?
Да. Каждый урок Lua Academy включает встроенный редактор кода, поэтому ты пишешь и запускаешь реальный код прямо в браузере и получаешь моментальную обратную связь от AI — локальная установка не требуется.
Все уроки этого курса
- Таблицы как массивы
- Таблицы как словари
- Перебор таблиц с pairs и ipairs
- Вложенные таблицы и структурированные данные