2
votes

How can I read a full table in a full table?

test = {}
test["Hello"] = "World"
test["tab"] = {}
test["tab"]["example"] = "ex"
test["tab"]["whats"] = "up"
test["seta"] = {}
test["seta"]["ask"] = "question"
test["seta"]["hard"] = {}
test["seta"]["hard"]["cool"] = "lua"

This is a exaple Table I would like to read. I need a table with this content:

"test.Hello" "World"
"test.tab.example" "ex"
"test.tab.whats" "up"
"test.seta.ask" "question"
"test.seta.hard.cool" "lua"

Left is the indexer and right the content. Has anybody a idea? That table I would read can also be

Thats["a"]["very"]["big"]["table"]

Or biger. Thankyou for your answers.

2

2 Answers

1
votes

First, solve the problem for tables with key strings and key values (i.e., no nesting tables):

function longkeys(object)
    local out = {}
    for key, value in pairs(object) do
        table.insert(out, {longkey = key, value = value})
    end
    return out
end

for _, pair in pairs(longkeys(test)) do
    print("test." .. pair.longkey, pair.value)
end

This will correctly capture Hello mappin to World, but it will map, e.g., tab to table: 00B6A488.

We can modify the longkeys function to recursively inspect value whenever it's a table:

function longkeys(object)
    local out = {}
    for key, value in pairs(object) do
        if type(value) == "table" then
            local keysof = longkeys(value)
            for _, pair in pairs(keysof) do
                pair.longkey = key .. "." .. pair.longkey
                table.insert(out, pair)
            end
        else
            table.insert(out, {longkey = key, value = value})
        end
    end
    return out
end

This relies on observing the recursive structure of these 'longkeys'. If s[k] is t and L is a longkey of t with value v, then k .. "." .. L is a longkey of s with value v.

Note that the solution assumes the structure of the table is entirely string keys => string values | tables of that form.

This won't work with other data types, or with cyclical tables.

Also, keep in mind that the 'longkeys' spit out by this function aren't necessarily valid Lua expressions for getting values out; consider a table with keys

local bad = {
    ["break"] = "break",
    ["i have a space"] = "space",
    ["i.have.dots"] = "dots",
    ["i\\have\"quotes"] = "quotes",
}

The output will give

bad.break
bad.i have a space
bad.i.have.dots
bad.i\have"quotes

none of which are valid ways to access the bad table

-1
votes
local function f(r, t, p)
   for k, v in pairs(t) do
      if type(v) == "table" then 
         f(r, v, p..k..".")
      else 
         r[p..k] = v
      end
   end
end

local result = {}
f(result, test, "test.")