Добавлен , опубликован

Руководство по Lua 5.1

Содержание:
В Lua таблицы - "собирательный" тип данных, представляющие из себя ассоциативные массивы, то есть они сохраняют данные по типу "ключ-значение"

Создание таблицы

Таблицы создаются при помощи двойных фигурных скобок { } .
Создадим пустую таблицу:
    > t = {}    -- создаём пустую таблицу, присваиваем её переменной t
    > print(t)
    table: 0035AE18
Обратите внимание, когда мы попытались отобразить таблицу, напечатались только её тип и уникальный id.
Чтобы отобразить данные таблицы, нужно использовать другой метод, но о нём позже.

Использование таблиц

Чтобы получить доступ к данным в таблице по ключу, мы используем следующую конструкцию: table [key]
    > t = {}
    > t["foo"] = 123 -- устанавливаем значение 123 по ключу "foo" в таблице
    > t[3] = "bar" --устанавливаем значение  "bar" по ключу 3 в таблице
    > = t["foo"]
    123
    > = t[3]
    bar
Если по данному ключу нету значения, возвращается nil
    > t = {}
    > = t["foo"]
    nil
Можно удалить пару "ключ-значение", установив значение nil по ключу.
Любое значение может быть использовано как ключ, кроме nil и NaN (несуществующее число)
    > t = {}
    > k = {}
    > f = function () end
    > t[k] = 123
    > t[f] = 456
    > = t[k]
    123
    > = t[f]
    456
    > t[nil] = 123
    stdin:1: table index is nil
    stack traceback:
            stdin:1: in main chunk
            [C]: in ?
    > t[0/0] = 123
    stdin:1: table index is NaN
    stack traceback:
            stdin:1: in main chunk
            [C]: in ?
Довольно часто строки используют как ключ: для них есть специальные сокращения:
    > t = {}
    > t.foo = 123 --тоже, что и  t["foo"] (не путайте с t[foo], что использует переменную foo как ключ)
    > = t.foo
    123
    > = t["foo"]
    123
Такие сокращения доступны для строк, содержащие знаки подчёркивания, буквы, числа (но не начинающиеся с чисел!)
Можно добавлять данные сразу при создании таблицы:
    > t = {["foo"] = "bar", [123] = 456}
    > = t.foo
    bar
    > = t[123]
    456
Тут точно также можно использовать сокращения:
    > t = {foo = "bar"} -- same as ["foo"]="bar" (but not [foo]="bar" , that would use the variable foo)
    > = t["foo"]
    bar
Для перебора всех данных в таблице, используется итератор pairs
    > t = {foo = "bar", [123] = 456}
    > for key,value in pairs(t) do print(key,value) end
    foo bar
    123 456
Порядок в котором перебирается таблица не определён. Пусть вы и добавляли в таблицу данные в определённой последовательности, цикл может перебирать их в другом порядке.

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

В действительности в Lua нет массивов, однако можно использовать таблицы как массивы.
Для этого при создании таблицы, надо разделять список данных запятыми:
    > t = {"a", "b", "c"}
    > = t[1]
    a
    > = t[3]
    c
Можно и так:
    > t = {[1]="a", [2]="b", [3]="c"}
    > = t[1]
    a
    > = t[3]
    c
Можно совмещать синтаксис обычных таблиц и массивов:
    > t = {"a", "b", [123]="foo", "c", name="bar", "d", "e"}
    > for k,v in pairs(t) do print(k,v) end
    1       a
    2       b
    3       c
    4       d
    5       e
    123     foo
    name    bar
Индексация начинается с 1 (в отличии от многих других языков, где индексация начинается с 0).
Можно получить длину массива, используя оператор #
    > t = {"a", "b", "c"}
    > = #t
    3
Оператор # не считает элементы в массиве, а просто возвращает номер последнего ключа. Естественно, он выдаст неверный результат, если члены массива не последовательны.
Два способа, как добавить значение в конец массива:
    > t = {}
    > table.insert(t, 123)
    > t[#t+1] = 456
    > = t[1]
    123
    > = t[2]
    456
используя table.insert, можно вставлять значения в середину массивов, в этом случае он сдвигает индексы остальных значений:
    > t = {"a", "c"}
    > table.insert(t, 2, "b")
    > = t[1], t[2], t[3]
    a b c
table.remove удаляет объект из массива, также сдвигая индексы:
    > t = {"a", "b", "c"}
    > table.remove(t, 2)
    > = t[1], t[2]
    a c
Для перебора массивов используется итератор ipairs. В отличии от pairs, перебирает массивы по порядку:
    > t = {"a", "b", "c"}
    > for i, v in ipairs(t) do print(i, v) end
    1       a
    2       b
    3       c
Для соединения строк в массиве используется функция table.concat. Функция принимает параметры separator (разделитель), start (начало) и end (конец).
Пример с разделителем:
    > t = {"a", "b", "c"}
    > = table.concat(t, ";")
    a;b;c
Табличные значения - ссылочные.
Когда мы назначаем таблицу переменной, мы не создаём новую таблицу, мы получаем ссылку на неё:
    > t = {}
    > u = t
    > u.foo = "bar"
    > = t.foo
    bar
    > function f(x) x[1] = 2 end
    > f(t)
    > = u[1]
    2
Таблицы удаляются из памяти "сборщиком мусора", когда исчезает последняя ссылка на неё.
Также следует помнить, что при сравнении таблиц используются ссылки на таблицы:
> table1 = {}
> table2 = {}
> table3 = table1
> = table1 == table2 -- разные таблицы
false
> = table1 == table3 -- ссылаются на одну таблицу
true
В Lua нет стандартных функций для копирования таблиц, так что это придётся делать ручками.

Таблицы как неупорядоченные списки

Часто новички в Lua создают массивы для хранения разных объектов. Проблема в том, что удаление объектов из такого массива и проверка находится ли объект в массиве - медлительны (приходится постоянно перебирать массив)
Проблему можно решить так: добавляем объект в ключ и устанавливаем ему значение-пустышку (например true). Таким образом можно использовать неупорядоченные списки с быстрым доступом к объектам, добавлением и удалением.
Отличия от обычных массивов в том, что нельзя будет добавить один и тот же объект дважды, и для получения кол-ва объектов всё же придётся перебирать список.
    local items = {}

    -- добавляем объект в список
    items["foo"] = true
    items[123] = true

    --проверяем есть  ли значение "foo"в списке
    if items["foo"] then
      -- тут может быть ваш код
    end

    -- удаление объекта из списка
    items[123] = nil
данная статья является вольным переводом с сайта lua-users.org
с возможными дополнениями и изменениями