Home > OS >  Build a table recursively out of an unknown number of lists in Lua
Build a table recursively out of an unknown number of lists in Lua

Time:11-04

I have an unknown number of lists, for example looking like this:

local first =  {"ship", "truck"}
local second =  {"container", "crate"}
local third = {"box", "bag", "case"}
local fourth =  {"apple", "banana"}

I want to build a table where every item from every list contains everything in the next list, which in turn contains everything in the next list, etc...

However, I can't figure out how to recursively go through everything in every list to build the structure I want. It's easy enough to do with just two lists:

local function do_it(list_1, list_2)
    local toplevel = {}
    for _, item_1 in pairs(list_1) do
        toplevel[item_1] = {}
        for _, item_2 in pairs(list_2) do
            table.insert(toplevel[item_1], item_2)
        end
    end
    return toplevel
end

Returns

truck:
  1: container
  2: crate
ship:
  1: container
  2: crate

How would I get to something like:

truck:
  1: container
    1: box
      1: apple
      2: banana
    2: bag
      1: apple
      2: banana
    3: case
      1: apple
      2: banana
  2: container
    1: box
      1: apple
      2: banana
    2: bag
      1: apple
      2: banana
    3: case
      1: apple
      2: banana
     
ship:
  1: container
    1: box
      1: apple
      2: banana
    2: bag
      1: apple
      2: banana
    3: case
      1: apple
      2: banana
  2: container
    1: box
      1: apple
      2: banana
    2: bag
      1: apple
      2: banana
    3: case
      1: apple
      2: banana

CodePudding user response:

With at table that holds all the value where the index is the given depth, we can do this:

local data = {{"ship", "truck"}, {"container", "crate"}, {"box", "bag", "case"}, {"apple", "banana"}}

local function do_it(list, depth)
  local root = {}
  for _, item in ipairs(list[depth]) do
    root[item] = {}
    print(string.rep("-",depth) .. item)
    if depth   1 < #list then
      root[item] = do_it(list, depth   1)
    else
      for _, v in ipairs(list[depth   1]) do
        print(string.rep(" ",depth   1) .. v)
        table.insert(root[item], v)
      end
    end
  end
  return root
end

do_it(data, 1)
-ship
--container
---box
    apple
    banana
---bag
    apple
    banana
---case
    apple
    banana
--crate
---box
    apple
    banana
---bag
    apple
    banana
---case
    apple
    banana
-truck
--container
---box
    apple
    banana
---bag
    apple
    banana
---case
    apple
    banana
--crate
---box
    apple
    banana
---bag
    apple
    banana
---case
    apple
    banana
  • Related