Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Improve SMODS.deepfind #437

Open
wants to merge 3 commits into
base: main
Choose a base branch
from
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
64 changes: 17 additions & 47 deletions src/utils.lua
Original file line number Diff line number Diff line change
Expand Up @@ -1536,8 +1536,20 @@ local flat_copy_table = function(tbl)
return new
end

---Seatch for val anywhere deep in tbl. Return a table of finds, or the first found if immediate is provided.
SMODS.deepfind = function(tbl, val, immediate)
---Seatch for val anywhere deep in tbl. Return a table of finds, or the first found if args.immediate is provided.
SMODS.deepfind = function(tbl, val, mode, immediate)
--backwards compat (remove later probably)
if mode == true then
mode = "v"
immediate = true
end
if mode == "index" then
mode = "i"
elseif mode == "value" then
mode = "v"
elseif mode ~= "v" and mode ~= "i" then
mode = "v"
end
local seen = {[tbl] = true}
local collector = {}
local stack = { {tbl = tbl, path = {}, objpath = {}} }
Expand All @@ -1556,7 +1568,7 @@ SMODS.deepfind = function(tbl, val, immediate)
--for every table that we have
for i, v in pairs(currentTbl) do
--if the value matches
if v == val then
if (mode == "v" and v == val) or (mode == "i") and i == val then
--copy our values and store it in the collector
local newPath = flat_copy_table(currentPath)
local newObjPath = flat_copy_table(currentObjPath)
Expand All @@ -1583,51 +1595,9 @@ SMODS.deepfind = function(tbl, val, immediate)
return collector
end

--Seatch for val as an index anywhere deep in tbl. Return a table of finds, or the first found if immediate is provided.
--backwards compat (remove later probably)
SMODS.deepfindbyindex = function(tbl, val, immediate)
local seen = {[tbl] = true}
local collector = {}
local stack = { {tbl = tbl, path = {}, objpath = {}} }

--while there are any elements to traverse
while #stack > 0 do
--pull the top off of the stack and start traversing it (by default this will be the last element of the last traversed table found in pairs)
local current = table.remove(stack)
--the current table we wish to traverse
local currentTbl = current.tbl
--the current path
local currentPath = current.path
--the current object path
local currentObjPath = current.objpath

--for every table that we have
for i, v in pairs(currentTbl) do
--if the value matches
if i == val then
--copy our values and store it in the collector
local newPath = flat_copy_table(currentPath)
local newObjPath = flat_copy_table(currentObjPath)
table.insert(newPath, i)
table.insert(newObjPath, v)
table.insert(collector, {table = currentTbl, index = i, tree = newPath, objtree = newObjPath})
if immediate then
return collector
end
--otherwise, if its a traversable table we havent seen yet
elseif type(v) == "table" and not seen[v] then
--make sure we dont see it again
seen[v] = true
--and then place it on the top of the stack
local newPath = flat_copy_table(currentPath)
local newObjPath = flat_copy_table(currentObjPath)
table.insert(newPath, i)
table.insert(newObjPath, v)
table.insert(stack, {tbl = v, path = newPath, objpath = newObjPath})
end
end
end

return collector
return SMODS.deepfind(tbl, val, "i", immediate)
end

-- this is for debugging
Expand Down