Scripting HelpersARCHIVE
A little piece of Roblox history. Preserved for everyone, one question at a time.Read about the archive →
✓ ANSWER ACCEPTED

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

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)

2 comments

0

Would you consider indenting your code? It'd be much easier to read.

0

yes hold up

1 answer

✓ Accepted answer

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!

This discussion is preserved as it was. New answers, comments, and votes are closed.