How to find all traces of an object

Questions about the LÖVE API, installing LÖVE and other support related questions go here.
Forum rules
Before you make a thread asking for help, read this.
Post Reply
User avatar
Gunroar:Cannon()
Party member
Posts: 1085
Joined: Thu Dec 10, 2020 1:57 am

How to find all traces of an object

Post by Gunroar:Cannon() »

I want to find all traces of an object(e.g. table) but the function I have seems to be flawed (not finding all traces) somehow :(

Code: Select all

function traceObject(target,ignore,start)

    local isarray = function(x)
        return type(x) == "table" and x[1] ~= nil
    end

    local getiter = function(x)
        if isarray(x) then
            return ipairs
        elseif type(x) == "table" then
            return pairs
        end
        error("expected table", 3)
    end

    local function remove(t, x)
        local iter = getiter(t)
       for i, v in iter(t) do
            if v == x then
                if isarray(t) then
                    table.remove(t, i)
                    return true
                else
                    t[i] = nil
                    return true
                end
            end
        end
        return false
    end

    local done = {}
    local data = ""
    local count = 0
    local refs = {}
    local inspect = inspect or tostring
    local gotten = {}
    local printed = {}
    local _inspect = function(n) return inspect(n,1) end
    if type(ignore)=="string" then
        ignore = {_G, ignore}
    else
        ignore = {}
    end

    local function _traceObject(m,name,donemove)
        done[tostring(m)] = true
        --local donemove = donemove or {}
        local _printed = {}
        local function check(x,i)
        
            if i==target and not (x==ignore[2] and m==ignore[1]) then
                if not gotten[tostring(m)..x] then
                    local sp = " "
                    gotten[tostring(m)..x] = 1
                    table.insert(refs,{name or "_G",m})
        
                    if not printed[tostring(m)] then
                        for cc = 1,#refs do
                            local r = refs[cc]
                            local name, value = r[1],r[2]
                            if not _printed[tostring(value)..name] then
                                data = string.format("%s\n%sMoving to index %s: ",data,sp,name)
                                sp = string.format("%s    ",sp)
                                _printed[tostring(value)..name] = 1
                            end
                        end
                        printed[tostring(m)] = sp
                    end
                    sp = printed[tostring(m)]
                    data = string.format("%s\n%sFound target at index `%s`.",data,sp,x)
                    --return data
                    refs[#refs] = nil
                    for x, i in pairs(refs) do
                    --    refs = {}--[i] = nil--donemove[x] = nil
                    end
                end
            
            elseif type(i)=="table" and not done[tostring(i)] then
                local tt = {name or "_G",m}
                local name = name or "_G"
                
                table.insert(refs,tt)
                _traceObject(i,x)
                remove(refs,tt)
               
            end
        end
        
        for x,i in pairs(m) do
            check(x,i)
        end
        for x,i in ipairs(m) do
            check(x,i)
        end
        return data
    end
    local data = _traceObject(start or _G)
    if data=="" then
        data = "Not Found!"
    end
    return data
end
--[[
Use:
    traceObject(table object[, table/string ignore])
        table object: object(mostly table, can be other) that should be traced
        table ignore: {table parent, string name}, ignore entries of key 'name' in parent
        string ignore: ignores global variable put in ignore
        returns: string representing trace

    
--example
t = {"hey"}
gotcha = {["that"]=t}
gotcha.forge = {hey={7,8,9,k={0,["that"]=t,["y"]={"can",t},nu={7,7,t}},t,t}}


--print traces ignoring key "that" at table gotcha
print(traceObject(gotcha.that,{gotcha,"that"}))

--print traces ignoring key "t" at global table
print(traceObject(gotcha.that,"t"))

--print all traces
print(traceObject(gotcha.that))

--print all traces of string "can"
print(traceObject("can,"t"))
  ]]
Anyone have an idea on another function on how to trace an object?
The risk I took was calculated,
but man, am I bad at math.

-How to be saved and born again :huh:
User avatar
darkfrei
Party member
Posts: 1169
Joined: Sat Feb 08, 2020 11:09 pm

Re: How to find all traces of an object

Post by darkfrei »

Use pairs, not ipairs.

Or use the fast_remove:

Code: Select all

function fast_remove (tabl, index)
    tabl[index]=tabl[#tabl]
    tabl[#tabl]=nil
end
 
It needs less time, but break the array.
:awesome: in Lua we Löve
:awesome: Platformer Guide
:awesome: freebies
Post Reply

Who is online

Users browsing this forum: No registered users and 54 guests