Как я могу l oop через вложенные таблицы в Lua, когда вложенные таблицы смешиваются с другими типами данных? - PullRequest
1 голос
/ 21 января 2020

Я пытаюсь l oop, хотя очень большая таблица в Lua, которая состоит из смешанных типов данных многих вложенных таблиц. Я хочу напечатать всю таблицу данных на консоль, но у меня проблемы с вложенными циклами. Когда я делаю вложенную l oop для печати пар ключей-значений следующего уровня, я получаю эту ошибку bad argument #1 to 'pairs' (table expected, got number), потому что не все значения являются таблицами.

Я пытался добавить if type(value) == table then перед вложенными l oop, но никогда не срабатывает, потому что type(value) возвращает userdata, независимо от того, являются ли они целыми числами, строками или таблицами.
РЕДАКТИРОВАТЬ: я ошибся, только таблицы возвращаются как тип userdata

Моя таблица выглядит примерно так, но сотни пар и могут быть несколькими вложенными таблицами. У меня есть отличный встроенный метод printall() с помощью инструмента, который я использую для этого, но он работает только на первой вложенной таблице. Я не имею никакого контроля над тем, как выглядит эта таблица, я просто играю с данными игры, любая помощь приветствуется.

myTable = {
    key1 = { value1 = "string" },
    key2 = int,
    key3 = {             -- printall() will print all these two as key value pairs
        subKey1 = int, 
        subKey2 = int
    },
    key4 = {
        innerKey1 = { -- printall() returns something like : innerKey1 = <int32_t[]: 0x13e9dcb98>
            nestedValue1 = "string",
            nestedValue2 = "string"
        },
        innerKey2 = { -- printall() returns something like : innerKey2 = <vector<int32_t>[41]: 0x13e9dcbc8>
            nestedValue3 = int,
            nestedValue4 = int
        }
    },
    keyN = "string"
}

My l oop

for key, value in pairs(myTable) do
    print(key)
    printall(value)
    for k,v in pairs(value) do
            print(k)
            printall(v)
        end
    end
    print("====")
end

ОТВЕТ: Вот моя последняя версия функции, которая исправила это, она немного изменена по сравнению с ответом, который дал Nifim, чтобы поймать крайние случаи, которые ее ломали.

function printFullObjectTree(t, tabs)
    local nesting = ""
    for i = 0, tabs, 1 do
        nesting = nesting .. "\t"
    end
    for k, v in pairs(t) do
        if type(v) == "userdata" then     -- all tables in this object are the type `userdata` 
            print(nesting .. k .. " = {")
            printFullObjectTree(v, tabs + 1)
            print(nesting .. "}")
        elseif v == nil then
            print(nesting .. k .. " = nil")
        elseif type(v) == "boolean" then
            print(nesting .. k .. " = " .. string.format("%s", v))
        else
            print(nesting .. k .. " = " .. v)
        end
    end
end

1 Ответ

2 голосов
/ 21 января 2020

type(value) возвращает строку, представляющую тип значения

Подробнее об этом здесь: lua -users.org / wiki / TypeIntrospection

Дополнительно Ваша таблица примера имеет int как некоторые значения для некоторых ключей, так как это будет ноль, эти ключи по существу не являются частью таблицы для моего примера ниже, я заменю каждый экземпляр int на числовое значение.

Было бы также целесообразно выполнять рекурсию, если вы нажмете на стол, а не создадите неизвестное количество вложенных циклов.

здесь приведен пример работы printAll

myTable = {
    key1 = { value1 = "string" },
    key2 = 2,
    key3 = {             -- printall() will print all these two as key value pairs
        subKey1 = 1, 
        subKey2 = 2
    },
    key4 = {
        innerKey1 = { -- printall() returns something like : innerKey1 = <int32_t[]: 0x13e9dcb98>
            nestedValue1 = "string",
            nestedValue2 = "string"
        },
        innerKey2 = { -- printall() returns something like : innerKey2 = <vector<int32_t>[41]: 0x13e9dcbc8>
            nestedValue3 = 3,
            nestedValue4 = 4
        }
    },
    keyN = "string"
}

function printAll(t, tabs)
    local nesting = ""
    for i = 0, tabs, 1 do
        nesting = nesting .. "\t"
    end
    for k, v in pairs(t) do
        if type(v) == "table" then
            print(nesting .. k .. " = {")
            printAll(v, tabs + 1)
            print(nesting .. "}")
        else
            print(nesting .. k .. " = " .. v)
        end
    end
end

print("myTable = {")
printAll(myTable, 0)
print("}")
...