1

I'm trying loop though a very large table in Lua that consists of mixed data types many nested tables. I want to print the entire data table to the console, but I'm having trouble with nested loops. When I do a nested loop to print the next level deep Key Value pairs I get this error bad argument #1 to 'pairs' (table expected, got number) because not all values are tables.

I've tried adding a if type(value) == table then before the nested loop but it never triggers, because type(value) returns userdata whether they are ints, strings or tables.
EDIT: I was wrong, only tables are returned as type userdata

My table looks something like this but hundreds of pairs and can be several nested tables. I have a great built in method printall() with the tool I'm using for this but it only works on the first nested table. I don't have any control over what this table looks like, I'm just playing with a game's data, any help is appreciated.

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 loop

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

ANSWER : Here is my final version of the function that fixed this, it's slightly modified from the answer Nifim gave to catch edge cases that were breaking it.

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
0

1 Answer 1

2

type(value) returns a string representing the type of value

More information on that Here: lua-users.org/wiki/TypeIntrospection

Additionally your example table has int as some of the values for some keys, as this would be nil those keys are essentially not part of the table for my below example i will change each instance of int to a number value.

It would also make sense to recurse if you hit a table rather than making a unknown number of nested loops.

here is an example of working 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("}")
Sign up to request clarification or add additional context in comments.

1 Comment

Thanks for the response. I had to make some modifications to handle edge cases but I got this to work nicely, I'll add the final version to my post since it's too long for this comment. I believe it's catching every value and table now.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.