Difference between revisions of "Module:Test/lib/search"
Jump to navigation
Jump to search
m |
|||
(5 intermediate revisions by the same user not shown) | |||
Line 1: | Line 1: | ||
− | local | + | local search = {} |
--------------- | --------------- | ||
-- conductor -- | -- conductor -- | ||
--------------- | --------------- | ||
− | -- sibling_key: optional, deprecate | + | -- 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"] = {}, | ["args"] = {}, | ||
["queried"] = {} | ["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 | if result then | ||
− | + | --~ search.generate_anscestry_of_last_search(result) | |
− | result.ancestors = | + | --~ result.ancestors = search.ancestors |
return result | return result | ||
end | end | ||
Line 38: | Line 39: | ||
-- ancestry -- | -- ancestry -- | ||
-------------- | -------------- | ||
− | function | + | --~ function search.generate_anscestry_of_last_search(quad) |
− | quad = quad or {} | + | --~ quad = quad or {} |
− | for _,v in ipairs( | + | --~ for _,v in ipairs(search.state.queried) do |
− | if v.value == quad.parent.table then | + | --~ if v.value == quad.parent.table then |
− | table.insert( | + | --~ 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 | + | --~ elseif not quad.parent.key then return nil |
− | end | + | --~ end |
− | end | + | --~ end |
− | end | + | --~ end |
---------------------- | ---------------------- | ||
-- search_condition -- | -- search_condition -- | ||
---------------------- | ---------------------- | ||
− | function | + | -- 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 | local condition = false | ||
− | if type(query) == | + | if type(query) == 'string' or type(query) == 'number' then |
condition = key == query | condition = key == query | ||
elseif query[1] and query[2] then | elseif query[1] and query[2] then | ||
Line 70: | Line 72: | ||
---------------- | ---------------- | ||
− | -- | + | -- find first -- |
---------------- | ---------------- | ||
− | function | + | search.meta = {} |
− | local | + | function search.find(query, tbl, parentKey) |
+ | local children = {} | ||
− | for k,v in pairs(tbl) do | + | for k,v in pairs(tbl) do -- search through children that are not tables |
local quad = { | local quad = { | ||
Line 81: | Line 84: | ||
value = v, | value = v, | ||
parent = { | parent = { | ||
− | key = | + | key = parentKey, |
table = tbl | table = tbl | ||
} | } | ||
} | } | ||
− | -- | + | --~ -- needed to generate ancestry |
− | table.insert( | + | --~ table.insert(search.state.queried, quad) |
− | if | + | if search.search_condition(query, k, v) then |
− | return | + | search.meta = quad |
+ | return v | ||
elseif type(v) == "table" then | elseif type(v) == "table" then | ||
− | table.insert( | + | table.insert(children, k) |
end | end | ||
end | end | ||
− | + | for _,childK in ipairs(children) do -- search through child tables | |
− | + | local found = search.find(query, tbl[childK], childK) | |
− | for _, | + | if found then return found end |
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | local | ||
− | if | ||
− | |||
end | end | ||
end | end | ||
− | return | + | return search -- return module |
Latest revision as of 12:59, 16 May 2021
This page has been marked as needing documentation of its function and purpose. You can help RimWorld Wiki by creating it here |
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