5

Is there a way that I can convert a hierarchy string into table form?

Suppose the input is A.B.C.D

ouput should be a table which traverses above input: A = {} A.B = {} A.B.C = {} A.B.C.D = {}

Thanks.

Darshan Nair
  • 323
  • 1
  • 5
  • 11

2 Answers2

5

The obvious solution would be to parse the string up and construct the hierarchy table from that. But a more clever solution is to let lua do it for you. With a bit of metamagic and function environment manipulation this can be done:

dump = require 'pl.pretty'.dump -- convenient table dumper from penlight

function createtable(str)
  local env_mt = {}
  env_mt.__index = function(t, k)
                     rawset(t, k, setmetatable({}, env_mt))
                     return rawget(t, k)
                   end
  local env = setmetatable({}, env_mt)
  local f = loadstring("return "..str)
  setfenv(f, env)
  f()
  return env
end

dump( createtable "A.B.C.D" )

this outputs:

{
  A = {
    B = {
      C = {
        D = {
        }
      }
    }
  }
}
greatwolf
  • 20,287
  • 13
  • 71
  • 105
5

@greatwolf's answer is right but I prefer the more straightforward approach of "parsing" the string and constructing the table. Less magic, and you do not execute a function loaded from a (possibly) user-defined string, which would be a security issue.

local createtable = function(str)
  local top = {}
  local cur = top
  for i in str:gmatch("[^.]+") do
    cur[i] = {}
    cur = cur[i]
  end
  return top
end

(require "pl.pretty").dump(createtable("A.B.C.D"))
catwell
  • 6,770
  • 1
  • 23
  • 21
  • 2
    Nice. Just note that `A` is not the table returned by createtable, but a field in that table. – lhf Jul 11 '13 at 13:16
  • Yes, I copied @greatwolf's output. If you want to return A you just have to skip the first part of the string, e.g. by changing the pattern to `"\.([^.]+)"`. – catwell Jul 11 '13 at 16:54