Cheat Engine Forum Index Cheat Engine
The Official Site of Cheat Engine
 
 FAQFAQ   SearchSearch   MemberlistMemberlist   UsergroupsUsergroups   RegisterRegister 
 ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 


iterate through every table in a table tree

 
Post new topic   Reply to topic    Cheat Engine Forum Index -> Cheat Engine Lua Scripting
View previous topic :: View next topic  
Author Message
HexaG0n
Advanced Cheater
Reputation: 0

Joined: 29 Mar 2021
Posts: 64

PostPosted: Sun Dec 26, 2021 10:36 am    Post subject: iterate through every table in a table tree Reply with quote

how can i iterate through all tables in a table? im trying to make an index finder that can
check if an object with the specified index exists in a table.

e.g. :

Code:
table_ = {
    taste = 'like freshly juiced delicious oranges',
    name = 'orange juice'
    recipe = {
        ingredients = {
            orange = '2',
            water = '200ml',
            sugar = '20g'
        },
        'blablabla',
        'blablabla',
        'Lastly, blablabla!'
    },
}

-- find the index "water" in table_
-- possible to have more indexes with "water",
-- add them to a seperate table


maybe some findIndex function or something like that.
Back to top
View user's profile Send private message
ByTransient
Expert Cheater
Reputation: 5

Joined: 05 Sep 2020
Posts: 240

PostPosted: Sun Dec 26, 2021 11:23 am    Post subject: Reply with quote

Code:
table_ = {
    taste = 'like freshly juiced delicious oranges',
    name = 'orange juice',
    recipe = {
        ingredients = {
            orange = '2',
            water = '200ml',
            sugar = '20g'
        },
        'blablabla',
        'blablabla',
        'Lastly, blablabla!'
    }
}

print(table_.name)
print(table_.recipe.ingredients.water)


I will join this.
Still, it's a question open to different solutions.
Back to top
View user's profile Send private message
TheyCallMeTim13
Wiki Contributor
Reputation: 50

Joined: 24 Feb 2017
Posts: 976
Location: Pluto

PostPosted: Sun Dec 26, 2021 11:33 am    Post subject: Reply with quote

You basically want a recursive loop.
https://en.wikipedia.org/wiki/Recursion_%28computer_science%29

Here's a simple example of one.
Code:
local function recursiveFunc(obj)
   local ret
   for key, _ in pairs(obj) do
      if key == 'somedata' then
         ret = obj[key]
      elseif type(obj[key]) == 'table' then
         ret = recursiveFunc(obj[key])
      end
   end
   return ret
end


local tbl = {
   notsomedata = 1,
   {
      notsomedata2 = 2,   
      {
         somedata = 3
      },
   },
}

print(recursiveFunc(tbl))

_________________
Back to top
View user's profile Send private message Visit poster's website
ByTransient
Expert Cheater
Reputation: 5

Joined: 05 Sep 2020
Posts: 240

PostPosted: Sun Dec 26, 2021 12:50 pm    Post subject: Reply with quote

I think you can expand on that.

Code:
table_ = {
    taste = 'like freshly juiced delicious oranges',
    name = 'orange juice',
    recipe = {
        ingredients = {
            orange = '2',
            water = '200ml',
            sugar = '20g'
        },
        'blablabla',
        'blablabla',
        'Lastly, blablabla!'
    }
}

--print(table_.name)
--print(table_.recipe.ingredients.water)

function datatype(tbl)
for i,k in pairs(tbl) do
   if type(tbl[i])=="table" then
     print("data: "..i)
       for j,l in pairs(tbl[i]) do
        print("data: "..j)
       end
     else
     print("name: "..k)
   end
  end
end

for i,k in pairs(table_) do
if type(table_[i])=="table" then
k2=datatype(table_[i])
print("data: "..i)
else
print("name: "..i) --i=name k=desc..
end
end

Back to top
View user's profile Send private message
LeFiXER
Grandmaster Cheater Supreme
Reputation: 20

Joined: 02 Sep 2011
Posts: 1054
Location: 0x90

PostPosted: Sun Dec 26, 2021 5:05 pm    Post subject: Reply with quote

You can try this.
Code:

function print_table(node)
  local cache, stack, output = {},{},{}
  local depth = 1
  local output_str = "{\n"

  while true do
    local size = 0
    for k,v in pairs(node) do
      size = size + 1
    end

    local cur_index = 1
    for k,v in pairs(node) do
      if (cache[node] == nil) or (cur_index >= cache[node]) then

        if (string.find(output_str,"}",output_str:len())) then
          output_str = output_str .. ",\n"
        elseif not (string.find(output_str,"\n",output_str:len())) then
          output_str = output_str .. "\n"
        end

        -- This is necessary for working with HUGE tables otherwise we run out of memory using concat on huge strings
        table.insert(output,output_str)
        output_str = ""

        local key
        if (type(k) == "number" or type(k) == "boolean") then
          key = "["..tostring(k).."]"
        else
          key = "['"..tostring(k).."']"
        end

        if (type(v) == "number" or type(v) == "boolean") then
          output_str = output_str .. string.rep('\t',depth) .. key .. " = "..tostring(v)
        elseif (type(v) == "table") then
          output_str = output_str .. string.rep('\t',depth) .. key .. " = {\n"
          table.insert(stack,node)
          table.insert(stack,v)
          cache[node] = cur_index+1
          break
        else
          output_str = output_str .. string.rep('\t',depth) .. key .. " = '"..tostring(v).."'"
        end

        if (cur_index == size) then
          output_str = output_str .. "\n" .. string.rep('\t',depth-1) .. "}"
        else
          output_str = output_str .. ","
        end
      else
        -- close the table
        if (cur_index == size) then
          output_str = output_str .. "\n" .. string.rep('\t',depth-1) .. "}"
        end
      end

      cur_index = cur_index + 1
    end

    if (size == 0) then
      output_str = output_str .. "\n" .. string.rep('\t',depth-1) .. "}"
    end

    if (#stack > 0) then
      node = stack[#stack]
      stack[#stack] = nil
      depth = cache[node] == nil and depth + 1 or depth - 1
    else
      break
    end
  end

  -- This is necessary for working with HUGE tables otherwise we run out of memory using concat on huge strings
  table.insert(output,output_str)
  output_str = table.concat(output)

  print(output_str)
end
Back to top
View user's profile Send private message
panraven
Grandmaster Cheater
Reputation: 55

Joined: 01 Oct 2008
Posts: 941

PostPosted: Mon Dec 27, 2021 6:57 am    Post subject: This post has 1 review(s) Reply with quote

Here a table iterator
https://pastebin.com/LZ1jLneh

Look for test example.

In hurry, may added example to see if it fit your case later.

bye~

updated, use OP's problem as test example.

_________________
- Retarded.


Last edited by panraven on Mon Dec 27, 2021 11:07 am; edited 1 time in total
Back to top
View user's profile Send private message
ByTransient
Expert Cheater
Reputation: 5

Joined: 05 Sep 2020
Posts: 240

PostPosted: Mon Dec 27, 2021 7:53 am    Post subject: Reply with quote

panraven wrote:
Here a table iterator
https://pastebin.com/LZ1jLneh


This example was helpful for me.
Thanks and +1

Code:
--  test

table_ = {
    taste1 = 'like freshly juiced delicious oranges',
    name1 = 'orange juice',
    recipe1 = {
        ingredients1 = {
            orange1 = '12',
            water1 = '1200ml',
            sugar1 = '120g'
        }
    },
    taste2 = 'like freshly juiced delicious oranges',
    name2 = 'orange juice',
    recipe2 = {
        ingredients2 = {
            orange2 = '22',
            water2 = '2200ml',
            sugar2 = '220g'
        }
    },
    taste3 = 'like freshly juiced delicious oranges',
    name3 = 'orange juice',
    recipe3 = {
        ingredients3 = {
            orange3 = '32',
            water3 = '3200ml',
            sugar3 = '320g'
        }
    }

}

result:
Code:
 >  taste3 : like freshly juiced delicious oranges
 >  name2 : orange juice
 >  taste2 : like freshly juiced delicious oranges
 >  taste1 : like freshly juiced delicious oranges
 >  name1 : orange juice
 >  >  >  recipe3.ingredients3.orange3 : 32
 >  >  >  recipe3.ingredients3.sugar3 : 320g
 >  >  >  recipe3.ingredients3.water3 : 3200ml
 >  >  >  recipe1.ingredients1.orange1 : 12
 >  >  >  recipe1.ingredients1.water1 : 1200ml
 >  >  >  recipe1.ingredients1.sugar1 : 120g
 >  name3 : orange juice
 >  >  >  recipe2.ingredients2.water2 : 2200ml
 >  >  >  recipe2.ingredients2.orange2 : 22
 >  >  >  recipe2.ingredients2.sugar2 : 220g
Back to top
View user's profile Send private message
salumor
Advanced Cheater
Reputation: 0

Joined: 14 Jan 2019
Posts: 84

PostPosted: Tue Dec 28, 2021 4:26 pm    Post subject: Reply with quote

Hm, I do wonder, did anyone check f.e. https://stackoverflow.com/questions/9168058/how-to-dump-a-table-to-console ?
Many examples on how to iterate through tables depending on the table and the output needed. (some of them alrdy here)
Does of course not include the compare part. But that's easy though still depends if you just want to print, or save for later use.
Back to top
View user's profile Send private message
Dark Byte
Site Admin
Reputation: 457

Joined: 09 May 2003
Posts: 25262
Location: The netherlands

PostPosted: Tue Dec 28, 2021 4:58 pm    Post subject: Reply with quote

also try it on this table:
Code:

x={}
y={}
x.text="bla"
x.child=y

y.text="weee"
y.parent=x

_________________
Do not ask me about online cheats. I don't know any and wont help finding them.

Like my help? Join me on Patreon so i can keep helping
Back to top
View user's profile Send private message MSN Messenger
TheyCallMeTim13
Wiki Contributor
Reputation: 50

Joined: 24 Feb 2017
Posts: 976
Location: Pluto

PostPosted: Tue Dec 28, 2021 5:26 pm    Post subject: Reply with quote

Dark Byte wrote:
also try it on this table:
Code:

x={}
y={}
x.text="bla"
x.child=y

y.text="weee"
y.parent=x


Dark Byte with the curve ball.

Basically all of these will get stuck in an endless loop. But "inspect.lua" doesn't but it only works on lua tables and not userdata. But it doesn't seem like you need to worry about userdata. So it might be a good place to look for some inspiration.

_________________
Back to top
View user's profile Send private message Visit poster's website
salumor
Advanced Cheater
Reputation: 0

Joined: 14 Jan 2019
Posts: 84

PostPosted: Tue Dec 28, 2021 5:26 pm    Post subject: Reply with quote

Dark Byte wrote:
also try it on this table:

You mean this result is not allowed? https://pastebin.com/DX36fRXK Confused dislike

https://stackoverflow.com/questions/9168058/how-to-dump-a-table-to-console/42062321#42062321 results f.e.

Code:
{
   ['child'] = {
      ['parent'] = {
   ['text'] = 'bla'
},
['text'] = 'weee'
},
['text'] = 'bla'
}
Back to top
View user's profile Send private message
HexaG0n
Advanced Cheater
Reputation: 0

Joined: 29 Mar 2021
Posts: 64

PostPosted: Sun Jan 09, 2022 3:05 am    Post subject: Reply with quote

going back to this topic, i finally found something that works for me online.
thank you everyone for the replies too, i appreciate them Very Happy

source : https://stackoverflow.com/questions/9168058/how-to-dump-a-table-to-console/42062321#47392487

here:
Code:
function findTblObj(tbl, obj, type_, path_sep)
    -- Source: https://stackoverflow.com/questions/9168058/how-to-dump-a-table-to-console/42062321#47392487

    local objs = {}
    local path_sep = path_sep or ' -> '
    local function findTblObj_(tbl, obj, type_, s_)
        for i, v in pairs(tbl) do
            local path = tostring(i) .. path_sep
            local full_path = (s_ or '') .. path

            if type(v) == 'table' then
                findTblObj_(v, obj, type_, full_path)

            else
                local obj_ = {full_path:sub(1,-#path_sep - 1), i, v}

                if type_ == 'index' then
                    if i == obj then
                        objs[#objs+1] = obj_
                    end

                elseif type_ == 'value' then
                    if v == obj then
                        objs[#objs+1] = obj_
                    end

                else
                    if i == obj or v == obj then
                        objs[#objs+1] = obj_
                    end
                end
            end
        end
    end
    findTblObj_(tbl, obj, type_)

    return objs
end

local table_ = {
    taste = 'like freshly juiced delicious oranges',
    name = 'orange juice',
    recipe = {
        ingredients = {
            orange = '2',
            water = '200ml',
            sugar = '20g'
        },
        'blablabla',
        'blablabla',
        'Lastly, blablabla!',
        water = 'crazy'
    },
    water = 'cool',
}

local test = findTblObj(table_, 'water', 'index', ' - ')
-- result [ json ] :

--[[
[
    ["recipe - water","water","crazy"],
    ["recipe - ingredients - water","water","200ml"],
    ["water","water","cool"]
]
]]
[/url]
Back to top
View user's profile Send private message
Display posts from previous:   
Post new topic   Reply to topic    Cheat Engine Forum Index -> Cheat Engine Lua Scripting All times are GMT - 6 Hours
Page 1 of 1

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum
You cannot attach files in this forum
You can download files in this forum


Powered by phpBB © 2001, 2005 phpBB Group

CE Wiki   IRC (#CEF)   Twitter
Third party websites