Scripting Helpers is winding down operations and is now read-only. More info→
Ad
Log in to vote
0

How can I distinguish the different "levels" of recursion?

Asked by
Trew86 175
5 years ago
Edited 5 years ago

This is kind of a follow-up question for one I asked earlier. I have my function called tableRec. I added the level variable with the help of len_ny. However it seems the script still won't distinguish the levels of recursion, as the output doesn't print when the level 3 has been reached, and trackPoint remains as nil, causing an error.

module.tableRec = function(tab, func)
     if type(tab) ~= "table" then return end 
     local level = 0; 
     for i, v in pairs(tab) do 
         level = level + 1 
         func(i, v, level) 
         module.tableRec(v, func, level) 
     end 
 end 

 functions.tableRec(module, function(a, b, lvl)
     local trackPoint 
     if lvl == 3 then 
         print("level 3 of recursion has been reached") 
         trackPoint = b 
     end 
     if a == "Sensor" then 
         functions.tableRec(module, function(i, v, level) 
             local adjacentBlock 
             if level == 1 then adjacentBlock = v end 
             if i == "Sensor" then 
                 if v == trackPoint.Sensor then 
                 trackPoint.Adjacent = adjacentBlock 
             end 
        end 
     end) 
     elseif a == "PathOptions" then 
         for i = 1, #b do 
             b[i].Status = Instance.new("IntValue")
         end 
     end 
 end)
0
Would you consider indenting your code? It'd be much easier to read. BlueGrovyle 278 — 5y
0
yes hold up Trew86 175 — 5y

1 answer

Log in to vote
0
Answered by 5 years ago

I believe you have some faulty logic in your recursion, assuming that different "recursion levels" refer to tables within tables. To begin to debug, we simplify the problem by testing a simple case that just prints out what your recursion provides to the function to check if it is working as intended in the first place. As you can see, somthing is wrong.

--Function with test table
function tableRec(tab, func)
    if type(tab) ~= "table" then return end
    local level = 0;
    for i, v in pairs(tab) do
        level = level + 1
        func(i, v, level)
        tableRec(v, func, level)
    end
end

--Test table. Contains tables for recursion and hardcoded recursion levels
local testTbl = {
    ["level"] = 0,
    ["Recursion1"] = {
        ["level"] = 1,
        ["Recursion2"] = {
            ["level"] = 2,
            ["Recursion3"] = {
                ["level"] = 3
            }
        },
    }
}
tableRec(testTbl, function(index, value, level) 
    print(tostring(index).."\t"..tostring(value).."\t"..level) 
    end)

Output (Edited for Clarification):

--Format is (index, value, recursionlevel)
level   0   2
Recursion1 table: 00000176DFD522D0 1
    level   1   2
    Recursion2 table: 00000176DFD52550 1
        level   2   2
        Recursion3 table: 00000176DFD51F60 1
            level   3   1

As you can see, your function provides recursion levels that clearly don't match the hard-coded, correct values (The 2nd and 3rd printouts). This is because, in your function, you increment the level with each object found in the given table, not with each new recursion spawned. Also, the new level passed to tableRec is completely ignored

function tableRec(tab, func) --Level is never passed here!
    for i, v in pairs(tab) do 
         level = level + 1 --This line increments level with each new object found in the table, not each new level.
         func(i, v, level) 
         tableRec(v, func, level) --Level is ignored in the new call!
     end 
 end

To fix this, we need to only increase the level when we pass a new level to a table. Here is the function, hopefully working as intended

function tableRec(tbl, func, level) --Add an OPTIONAL paremeter to be used in the recursion loop.
    --If we weren't passed a recursion level, assume we are starting a recursion loop and set to 0
     if not level then level = 0 end

    --Add printouts for debugging. Also, use typeof - (it's more compatible with ROBLOX)
     if typeof(tbl) ~= "table" then warn("Passed table not a table!") return end 
     for i, v in pairs(tbl) do 
        func(i, v, level) 
        if typeof(v) == "table" then --If we have found a table, call the recursive function on it!
            tableRec(v, func, level + 1) --Add one to the current level to indicate a new level of recursion
        end
     end 
 end

Output (With the same table as before):

level   0   0
Recursion1 table: 00000176E04896A0 0
    level   1   1
    Recursion2 table: 00000176E0488A70 1
        level   2   2
        Recursion3 table: 00000176E04894C0 2
            level   3   3

As you can see, the calculated level now matches with the hard-coded one! All in all, recursion can be difficult to wrap your mind around at first, but becomes an incredibly powerful tool once you get it. Good luck!

Ad

Answer this question