Module:Test/lib/search

From RimWorld Wiki
Jump to navigation Jump to search
The printable version is no longer supported and may have rendering errors. Please update your browser bookmarks and please use the default browser print function instead.

local search = {}

---------------
-- conductor --
---------------
-- ancestry functionality (commented out)
-- sibling_key: optional, deprecate the whole thing (commented out)

-- Possible query combinations:
--   query: {key, value}
--   query: {key, nil}
--   query: {nil, value}
--   query: key (string or number)
function search.conductor(query, tbl)
  assert(query, "conductor: missing argument #1 (query)")
  assert(tbl, "conductor: missing argument #2 (table to search through)")
  assert(type(tbl) == 'table', string.format("conductor: bad argument #2 (table expected, got %s)", type(tbl)))

  search.state = {
    ["args"] = {},
    ["queried"] = {}
  }
--~   search.ancestors = {}

  search.state.args.query = query
  search.state.args.table = tbl
--~   search.state.args.sibling_key = sibling_key

  local result = search.find(query, tbl)

  if result then
--~     search.generate_anscestry_of_last_search(result)
--~     result.ancestors = search.ancestors
    return result
  end
end

--------------
-- ancestry --
--------------
--~ function search.generate_anscestry_of_last_search(quad)
--~   quad = quad or {}

--~   for _,v in ipairs(search.state.queried) do
--~     if v.value == quad.parent.table then
--~       table.insert(search.ancestors, quad.parent.key)
--~       search.generate_anscestry_of_last_search(v, search.state.queried, ancestors)
--~     elseif not quad.parent.key then return nil
--~     end
--~   end
--~ end

----------------------
-- search_condition --
----------------------
-- note: if I want to search for true/false, will need to change this up a bit
function search.search_condition(query, key, value)
  local condition = false

  if type(query) == 'string' or type(query) == 'number' then
    condition = key == query
  elseif query[1] and query[2] then
    condition = key == query[1] and value == query[2]
  elseif query[1] then
    condition = key == query[1]
  elseif query[2] then
    condition = value == query[2]
  end

  return condition
end

----------------
-- find first --
----------------
search.meta = {}
function search.find(query, tbl, parentKey)
  local children = {}

  for k,v in pairs(tbl) do -- search through children that are not tables

    local quad = {
      key = k,
      value = v,
      parent = {
        key = parentKey,
        table = tbl
      }
    }

--~     -- needed to generate ancestry
--~     table.insert(search.state.queried, quad)

    if search.search_condition(query, k, v) then
      search.meta = quad
      return v
    elseif type(v) == "table" then
      table.insert(children, k)
    end

  end

  for _,childK in ipairs(children) do -- search through child tables
    local found = search.find(query, tbl[childK], childK)
    if found then return found end
  end
end

return search -- return module