Lua функции table.toString (tableName) и table.fromString (stringTable)? - PullRequest
4 голосов
/ 20 мая 2011

Я хочу преобразовать 2d таблицу lua в строку, а затем, после преобразования ее в строку, преобразовать ее обратно в таблицу, используя эту вновь созданную строку. Кажется, что этот процесс называется сериализацией и обсуждается в приведенном ниже URL-адресе, но мне трудно разобраться в коде, и я надеялся, что у кого-то здесь есть простые функции table.toString и table.fromString
http://lua -users.org / вики / TableSerialization

Ответы [ 5 ]

9 голосов
/ 21 мая 2011

Я использую следующий код для сериализации таблиц:

function serializeTable(val, name, skipnewlines, depth)
    skipnewlines = skipnewlines or false
    depth = depth or 0

    local tmp = string.rep(" ", depth)

    if name then tmp = tmp .. name .. " = " end

    if type(val) == "table" then
        tmp = tmp .. "{" .. (not skipnewlines and "\n" or "")

        for k, v in pairs(val) do
            tmp =  tmp .. serializeTable(v, k, skipnewlines, depth + 1) .. "," .. (not skipnewlines and "\n" or "")
        end

        tmp = tmp .. string.rep(" ", depth) .. "}"
    elseif type(val) == "number" then
        tmp = tmp .. tostring(val)
    elseif type(val) == "string" then
        tmp = tmp .. string.format("%q", val)
    elseif type(val) == "boolean" then
        tmp = tmp .. (val and "true" or "false")
    else
        tmp = tmp .. "\"[inserializeable datatype:" .. type(val) .. "]\""
    end

    return tmp
end

созданный код можно затем выполнить с помощью loadstring (): http://www.lua.org/manual/5.1/manual.html#pdf-loadstring, если вы передали аргумент параметру 'name' (или добавили его впоследствии):

s = serializeTable({a = "foo", b = {c = 123, d = "foo"}})
print(s)
a = loadstring(s)()
7 голосов
/ 20 мая 2011

Код, размещенный lhf, является гораздо более простым примером кода, чем что-либо со страницы, на которую вы ссылаетесь, так что, надеюсь, вы сможете понять его лучше.Адаптация его к выводу строки вместо печати вывода выглядит следующим образом:

t = {
{11,12,13},
{21,22,23},
}

local s = {"return {"}
for i=1,#t do
  s[#s+1] = "{"
  for j=1,#t[i] do
    s[#s+1] = t[i][j]
    s[#s+1] = ","
  end
  s[#s+1] = "},"
end
s[#s+1] = "}"
s = table.concat(s)

print(s)

Общая идея с сериализацией состоит в том, чтобы взять все биты данных из некоторой структуры данных, например таблицы, и затем выполнить цикл по этим данным.структура при построении строки, содержащей все эти биты данных вместе с символами форматирования.

4 голосов
/ 21 мая 2011

Как насчет модуля JSON ? Таким образом, у вас также есть лучшие обменные данные. Я обычно предпочитаю dkjson, который также поддерживает utf-8, а cmjjson - нет.

2 голосов
/ 20 мая 2011

Вот простая программа, которая предполагает, что ваша таблица содержит только цифры. Он выводит код Lua, который можно загрузить обратно с помощью loadstring()(). Приспособьте это к выводу к строке вместо распечатывания этого Подсказка: переопределите print, чтобы собрать выходные данные в таблицу, а затем в конце превратите выходную таблицу в строку с table.concat.

t = {
{11,12,13},
{21,22,23},
}

print"return {"
for i=1,#t do
        print"{"
        for j=1,#t[i] do
                print(t[i][j],",")
        end
        print"},"
end
print"}"
1 голос
/ 21 мая 2011

Предполагая, что:

  • У вас нет циклов (таблица ссылок на таблицы b и b, ссылающиеся на a)
  • Ваши таблицы являются чистыми массивами (все ключи являются последовательными положительными целыми числами)., начиная с 1)
  • Ваши значения являются целыми числами (без строк и т. д.)

Тогда рекурсивное решение легко реализовать:

function serialize(t)
  local serializedValues = {}
  local value, serializedValue
  for i=1,#t do
    value = t[i]
    serializedValue = type(value)=='table' and serialize(value) or value
    table.insert(serializedValues, serializedValue)
  end
  return string.format("{ %s }", table.concat(serializedValues, ', ') )
end

Prependстрока, полученная из этой функции с return, сохраните ее в файле .lua:

-- myfile.lua
return { { 1, 2, 3 }, { 4, 5, 6 } }

Вы можете просто использовать dofile , чтобы вернуть таблицу.

t = dofile 'myfile.lua'

Примечания:

  • Если у вас есть циклы, вам придется обращаться с ними явно - обычно с дополнительной таблицей, чтобы «отслеживать» повторы
  • Если выне иметь чистых массивов, тогда вам придется анализировать t по-разному, а также обрабатывать способ визуализации ключей (они являются строками, являются ли они другими таблицами? и т. д.).
  • Если у вас болеетолько целые и подтаблицы, тогда вычисление serializedValue будет более сложным.

Привет!

...