0Pricing
Lua Academy · Урок

Таблицы как массивы

Создавайте и изменяйте массивы с индексацией от 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 — локальная установка не требуется.

Все уроки этого курса

  1. Таблицы как массивы
  2. Таблицы как словари
  3. Перебор таблиц с pairs и ipairs
  4. Вложенные таблицы и структурированные данные
← Назад к Lua Academy