Таблицы как массивы
Создавайте и изменяйте массивы с индексацией от 1 с помощью table.insert и table.remove.
«Таблицы как массивы» — бесплатный урок Lua Academy на CoddyKit. Это урок 1 из 4. Ты можешь прочитать весь урок бесплатно ниже — а потом практиковать его прямо в браузере с встроенным редактором кода и ИИ-репетитором 24/7. Это часть пути обучения Lua Academy, и твой прогресс синхронизируется между веб-версией и приложением CoddyKit. Курс Lua Academy содержит 4 уроков всего.
Массивы с индексацией с 1
Массивы Lua — это таблицы с последовательными целочисленными ключами, начинающимися с 1. Это отличается от большинства языков, где отсчёт начинается с 0. Соглашение едино для Lua: все функции стандартной библиотеки предполагают индексацию с 1. Обращение за пределы массива возвращает nil, а не ошибку.
local colors = {"red", "green", "blue"}
print(colors[1]) -- red
print(colors[2]) -- green
print(colors[3]) -- blue
print(colors[0]) -- nil (no index 0)
print(#colors) -- 3 (length operator)table.insert и table.remove
table.insert(t, val) добавляет элемент в конец. table.insert(t, pos, val) вставляет элемент в указанную позицию, сдвигая остальные вправо. table.remove(t, pos) удаляет элемент в позиции pos (по умолчанию последний), сдвигает остальные влево и возвращает удалённое значение.
local stack = {}
table.insert(stack, "first")
table.insert(stack, "second")
table.insert(stack, "third")
print(#stack) -- 3
table.insert(stack, 2, "inserted")
print(stack[2]) -- inserted
local removed = table.remove(stack, 1)
print(removed) -- first
print(stack[1]) -- insertedСтек с помощью таблиц
Таблица Lua идеально подходит для реализации стека. Используйте table.insert для добавления и table.remove для извлечения. По умолчанию обе операции выполняются с концом таблицы, что обеспечивает амортизированное время O(1).
local stack = {}
-- Push
table.insert(stack, 10)
table.insert(stack, 20)
table.insert(stack, 30)
-- Pop
print(table.remove(stack)) -- 30
print(table.remove(stack)) -- 20
print(#stack) -- 1Очередь с помощью таблиц
Очередь (FIFO) можно реализовать с помощью таблицы, но table.remove(t, 1) выполняется за O(n), поскольку сдвигает все элементы. Для высокопроизводительных очередей используйте два указателя (индексы начала и конца), чтобы избежать сдвига.
local head, tail = 1, 0
local queue = {}
local function enqueue(v)
tail = tail + 1
queue[tail] = v
end
local function dequeue()
if head > tail then return nil end
local v = queue[head]
queue[head] = nil
head = head + 1
return v
end
enqueue("a"); enqueue("b"); enqueue("c")
print(dequeue()) -- a
print(dequeue()) -- bОператор длины #
Оператор # возвращает «границу» таблицы: индекс i, для которого t[i] ~= nil и t[i+1] == nil. Для последовательностей без пустых позиций это соответствует длине массива. При наличии пустых позиций (nil в середине) результат # не определён — используйте table.pack или отслеживайте длину вручную.
local t = {10, 20, 30, 40, 50}
print(#t) -- 5
-- Safe for dense arrays
for i = #t, 1, -1 do
io.write(t[i] .. " ")
end
print() -- 50 40 30 20 10Получение срезов массивов
В Lua нет встроенного среза, но можно извлечь подмассив с помощью table.move (в Lua 5.3 и новее) или ручного цикла. table.move(a1, f, e, t, a2) копирует элементы из a1[f..e] в a2, начиная с позиции t.
local src = {10,20,30,40,50,60}
-- Manual slice
local function slice(t, from, to)
local result = {}
for i = from, to do
result[#result+1] = t[i]
end
return result
end
local sub = slice(src, 2, 4)
print(sub[1], sub[2], sub[3]) -- 20 30 40Обращение массива
Разверните таблицу на месте, меняя местами элементы с обоих концов по направлению к середине. Это классический алгоритм, работающий с любым массивом Lua без дополнительной памяти.
local function reverse(t)
local n = #t
for i = 1, math.floor(n / 2) do
t[i], t[n - i + 1] = t[n - i + 1], t[i]
end
end
local arr = {1, 2, 3, 4, 5}
reverse(arr)
for _, v in ipairs(arr) do
io.write(v .. " ")
end
print() -- 5 4 3 2 1Объединение массивов
Чтобы объединить два массива в один, переберите второй массив и добавьте его элементы в конец. В Lua 5.3 и новее это эффективно выполняет table.move. В результате получается новая таблица, содержащая все элементы обоих массивов в исходном порядке.
local function concat(a, b)
local result = {}
for _, v in ipairs(a) do result[#result+1] = v end
for _, v in ipairs(b) do result[#result+1] = v end
return result
end
local merged = concat({1,2,3}, {4,5,6})
for i, v in ipairs(merged) do
io.write(v .. " ")
end
print() -- 1 2 3 4 5 6Рекурсивное выравнивание вложенных массивов
Рекурсивно выровняйте вложенный массив: если элемент является таблицей, рекурсивно обработайте её; в противном случае добавьте его в результат. Это естественное применение рекурсивного обхода таблиц.
local function flatten(t, result)
result = result or {}
for _, v in ipairs(t) do
if type(v) == "table" then
flatten(v, result)
else
result[#result+1] = v
end
end
return result
end
local nested = {1, {2, 3}, {4, {5, 6}}, 7}
local flat = flatten(nested)
print(table.concat(flat, ", ")) -- 1, 2, 3, 4, 5, 6, 7Массив как множество
Множество можно реализовать с помощью таблицы, где значения используются как ключи, а каждому значению соответствует true. Проверка принадлежности множеству выполняется за O(1). Построение множества из массива удаляет дубликаты. Чтобы снова получить массив, выполните перебор с помощью pairs.
local function toSet(arr)
local set = {}
for _, v in ipairs(arr) do set[v] = true end
return set
end
local nums = {3,1,4,1,5,9,2,6,5,3}
local set = toSet(nums)
local unique = {}
for k in pairs(set) do unique[#unique+1] = k end
table.sort(unique)
print(table.concat(unique, " ")) -- 1 2 3 4 5 6 9Быстрая проверка
Что делает table.remove(t), если вызвать её только с одним аргументом?
Итоги: таблицы как массивы
Краткое содержание:
- Массивы Lua — это таблицы с индексацией начиная с 1
table.insert/table.removeиспользуются для добавления и удаления элементов с конца#tвозвращает длину последовательностей без пропусков- Стек: добавление и удаление с конца (O(1))
- Очередь: используйте указатели на начало и конец, чтобы избежать сдвига за O(n)
- Используйте таблицу как множество для проверок принадлежности за O(1)
Часто задаваемые вопросы
Урок «Таблицы как массивы» бесплатный?
Да — полный текст урока «Таблицы как массивы» бесплатно доступен здесь в веб-версии. Чтобы практиковать его интерактивно (встроенный редактор кода и ИИ-репетитор 24/7) и разблокировать остальной курс Lua Academy, подпишись на CoddyKit PRO. Курс Lua Academy содержит 4 уроков всего.
Чему я научусь в уроке «Таблицы как массивы»?
Создавайте и изменяйте массивы с индексацией от 1 с помощью table.insert и table.remove. Ты практикуешь Lua Academy с помощью реального кода, который запускаешь прямо в браузере, и ИИ-репетитор 24/7 отвечает на твои вопросы во время урока.
Нужен ли мне опыт, чтобы начать Lua Academy?
Предыдущий опыт не требуется. Lua Academy на CoddyKit структурирован для всех уровней — от новичков до продвинутых, поэтому ты можешь начать отсюда или с самого начала и учиться в своем темпе. Это урок 1 из 4.
Сколько времени занимает урок «Таблицы как массивы»?
Большинство уроков CoddyKit занимают около 5–10 минут. Каждый из них компактный и интерактивный, поэтому ты постоянно делаешь прогресс и продолжаешь с того же места в веб-версии и приложении.
Можно ли писать и запускать код в этом уроке Lua Academy?
Да. Каждый урок Lua Academy включает встроенный редактор кода, поэтому ты пишешь и запускаешь реальный код прямо в браузере и получаешь моментальную обратную связь от AI — локальная установка не требуется.
Все уроки этого курса
- Таблицы как массивы
- Таблицы как словари
- Перебор таблиц с pairs и ipairs
- Вложенные таблицы и структурированные данные