Search code examples
luatraversallua-table

Getting all data names from a table


I have a nested table of global variables in my lua file like

GLOBAL.ADVANTAGES = 
{
CLASS =
{
    WARRIOR =
    {
        ATTACK = 0,
        DEFEND = 0,
        CRIT_CHANCE = 0,
        CRIT_DAMAGE = 0
    },
    PALADIN =
    {
        ATTACK = 0,
        DEFEND = 0,
        CRIT_CHANCE = 0,
        CRIT_DAMAGE = 0
    },
    PRIEST =
    {
        ATTACK = 0,
        DEFEND = 0,
        CRIT_CHANCE = 0,
        CRIT_DAMAGE = 0
    },
    ...
...

I want to traverse table to return all variable names in strings like "GLOBAL.CLASS.PRIEST.ATTACK", "GLOBAL.CLASS.PRIEST.DEFENSE", and so on. I already can traverse whole table but It returns values solely as "ATTACK", "DEFENSE" and such...

How can I get full "address" of each value?


Solution

  • More efficient and easier way is to use table.concat. For example, to show all fields:

    local myprint
    myprint = function(tab, prefixtab) -- Tab = tab to print, prefix = inital tab ({'GLOBAL'} in your case) or nil
        prefixtab = prefixtab or {}
        local idx = #prefixtab+1
        for k,v in pairs(tab) do
            prefixtab[idx] = k
            print(table.concat(prefixtab, '.')) -- Comment to don't print for every path
            if type(v) == 'table' then
                myprint(v, prefixtab)
            --else -- To print only complete pathes
                --print(table.concat(prefixtab, '.'))
            end
        end
        prefixtab[idx] = nil
    end
    

    Example (based on your table):

    > myprint(GLOBAL, {'GLOBAL'})
    GLOBAL.ADVANTAGES
    GLOBAL.ADVANTAGES.CLASS
    GLOBAL.ADVANTAGES.CLASS.WARRIOR
    GLOBAL.ADVANTAGES.CLASS.WARRIOR.CRIT_DAMAGE
    GLOBAL.ADVANTAGES.CLASS.WARRIOR.ATTACK
    GLOBAL.ADVANTAGES.CLASS.WARRIOR.CRIT_CHANCE
    GLOBAL.ADVANTAGES.CLASS.WARRIOR.DEFEND
    GLOBAL.ADVANTAGES.CLASS.PRIEST
    GLOBAL.ADVANTAGES.CLASS.PRIEST.CRIT_DAMAGE
    GLOBAL.ADVANTAGES.CLASS.PRIEST.ATTACK
    GLOBAL.ADVANTAGES.CLASS.PRIEST.CRIT_CHANCE
    GLOBAL.ADVANTAGES.CLASS.PRIEST.DEFEND
    GLOBAL.ADVANTAGES.CLASS.PALADIN
    GLOBAL.ADVANTAGES.CLASS.PALADIN.CRIT_DAMAGE
    GLOBAL.ADVANTAGES.CLASS.PALADIN.ATTACK
    GLOBAL.ADVANTAGES.CLASS.PALADIN.CRIT_CHANCE
    GLOBAL.ADVANTAGES.CLASS.PALADIN.DEFEND
    

    Or complete-only path version:

    > myprint(GLOBAL, {'GLOBAL'})
    GLOBAL.ADVANTAGES.CLASS.PRIEST.CRIT_CHANCE
    GLOBAL.ADVANTAGES.CLASS.PRIEST.ATTACK
    GLOBAL.ADVANTAGES.CLASS.PRIEST.CRIT_DAMAGE
    GLOBAL.ADVANTAGES.CLASS.PRIEST.DEFEND
    GLOBAL.ADVANTAGES.CLASS.WARRIOR.CRIT_CHANCE
    GLOBAL.ADVANTAGES.CLASS.WARRIOR.ATTACK
    GLOBAL.ADVANTAGES.CLASS.WARRIOR.CRIT_DAMAGE
    GLOBAL.ADVANTAGES.CLASS.WARRIOR.DEFEND
    GLOBAL.ADVANTAGES.CLASS.PALADIN.CRIT_CHANCE
    GLOBAL.ADVANTAGES.CLASS.PALADIN.ATTACK
    GLOBAL.ADVANTAGES.CLASS.PALADIN.CRIT_DAMAGE
    GLOBAL.ADVANTAGES.CLASS.PALADIN.DEFEND