title: Traversing nested tables in lua
body: <p>I'm new to lua and having a hard time with working with nested data structures.</p>
  
  <p>I am trying to write a hierarchy system where I have a table of three keys and the values are another table. The three top level keys are zone, region and environment in order of specificness for me. I want to use the most specific subvalue that is present in the table that is related to the keys of my environment variables.</p>
  
  <p>So given the table of data and environment variables below, I want to return the key for region.US since the zone variable does not exist in the table, although if it did that would be top priority. The key region.US does exist and is a higher priority than environment, therefore I should return ccc.</p>
  
  <p>Depending on how lua loads up the table, I get different results by string matching the top level key. How can I do this in Lua?</p>
  
  <pre><code>env_zone = 5  -- doesn't exist in table, but should return if it did
  env_region = US  -- exists and should return because env_zone doesn't exist
  env_environment = food  -- does exist but should not be returned because env_region is a higher priority
  
  
  zone:
    1: aaaaa
    2: bbbbb
  region:
    EU: ddd
    US: ccc
  environment:
    food: gggg
    prod: eee
    staging: fff
  </code></pre>
  
  <p>My code that doesn't work properly.</p>
  
  <pre><code>local cjson = require('cjson')
  
  function tprint (tbl, indent)
    if not indent then indent = 0 end
    for k, v in pairs(tbl) do
      formatting = string.rep("  ", indent) .. k .. ": "
      if type(v) == "table" then
        print(formatting)
        tprint(v, indent+1)
      elseif type(v) == 'boolean' then
        print(formatting .. tostring(v))
      else
        print(formatting .. v)
      end
    end
  end
  
  local function slurp(path)
      local f = io.open(path)
      local s = f:read("*a")
      f:close()
      return s
  end
  
  local json_string = slurp("data.json")
  local tab = cjson.decode(json_string)
  
  local zone_var = os.getenv("zone")   -- "fake"
  local region_var = os.getenv("region") -- "US"
  local env_var = os.getenv("env")     -- "food"
  
  local ok, err = pcall(
    function ()
      for key, value in pairs(tab) do
        if string.match(key, "zone") then --highest priority, check it first
          for subkey, subvalue in pairs(value) do
            if string.match(subkey, zone_var) then
              print(subvalue)
              return
            end
          end
        elseif string.match(key, "region") then --second highest priority
          for subkey, subvalue in pairs(value) do
            if string.match(subkey, region_var) then
              print(subvalue)
              return
            end
          end
        elseif string.match(key, "environment") then --last chance
          for subkey, subvalue in pairs(value) do
            if string.match(subkey, env_var) then
              print(subvalue)
              return
            end
          end
        end
      end
    end
  )
  tprint(tab)
  </code></pre>
  
  <p>Outputs: Should always be returning   ccc</p>
  
  <pre><code>➜  lua git:(integration) ✗ lua test1.lua
  gggg
  environment:
    staging: fff
    prod: eee
    food: gggg
  zone:
    2: bbbbb
    1: aaaaa
  region:
    US: ccc
    EU: ddd
  </code></pre>
  
  <p>...</p>
  
  <pre><code>➜  lua git:(integration) ✗ lua test1.lua
  ccc
  zone:
    1: aaaaa
    2: bbbbb
  region:
    EU: ddd
    US: ccc
  environment:
    food: gggg
    prod: eee
    staging: fff
  </code></pre>