1

I make a function to parsing path name and file name from a computer directory using Lua Cheat Engine, next I want store the results in to a Lua table.

My function :

function addSongList()
 load_dialog = createOpenDialog(self)
 load_dialog.InitalDir = os.getenv('%USERPROFILE%')
 load_dialog.Filter = 'MP3 files|*.mp3|*'
 load_dialog.execute()
 file = load_dialog.FileName
  if file then
 --- parsing path and filename
   local pathN = file:match("(.*[\\/])")
   local path, name = file:match('(.*\\)(.*)%.mp3')
 --- test  to open E:\MyMP3\mysong.mp3
   print(pathN)   --- result : E:\MyMP3\
   print(name)    --- result : mysong.mp3
  end
end

local mp3Table = {}
table.insert(mp3Table,{pathN,name})
  1. Is this correct way and correct syntax using table.insert(mp3Table,{pathN,name})
  2. How to check if elements already added to the table by print out them?
  3. How to clearing / empty the table ?

Thank you

JoeFern
  • 117
  • 1
  • 8

2 Answers2

1

1 - Inserting to the table:

table.insert(tb, value) inserts the value to de table tb. Using table.insert(mp3Table,{pathN,name}) you are dynamically creating a (sub)table and then appending to the main one.

2 - Printing the table.

As already pointed out you can just traverse the table using pairs or ipairs in order to get the elements. I prefer ipairs in this case because the table is numerically indexed and order is guaranteed in accordance to table.insert. The inner table must be indexed by numbers because you created it usign numeric indices.

for k, v in ipairs(mp3Table) do
    print(v[1], v[2])
end

But you can also opt for a metatable which will also give you the possibility to generate a string representation for the table:

mp3Table_mt = 
{
    __tostring = function(self)
        local ret = {}
        for k, v in ipairs(self) do
            table.insert(ret, v[1] .. "\t" .. v[2])
        end
        return table.concat(ret, "\n")
    end
}

When initializing mp3Table you have to assign the metatable

local mp3Table = setmetatable({}, mp3Table_mt)

Then you can just tell Lua to print the table:

print(mp3Table)

3 - Empty/Delete the table:

Well there are two different things here. One is empty another is delete.

Lua uses garbage collection so actual deleting only occurs when there are no more references to a particular table. What you can do to tell Lua you no longer need a variable is assing nil to it. If there is no other reference to the value your variable was pointing to, the GC will clean it when it runs.

But you can empty the table without deleting it. It may be tempting to say that mp3Table = {} "empties the table". But it does not. What you are doing in this case is assigning a fresh new table to mp3Table variable. And if any other variable is still pointing to the old table it will no get collected and the inner values will remain untouched. If there's no such other variable, the table will be garbage collected just as if you assigned nil to mp3Table variable.

So to effectivelly empty a table you have to traverse it and set all its variables to nil.

function clearTable(tb)
    for i, v in pairs(tb) do
        tb[i] = nil
    end
end

Specifically in the case asked, just assigning a new table to mp3Table may be enough because there are no more references to the same table. Assign nil afterwards is not necessary. What matters is if there are variables pointing to the same value. If you know what you are doing and the consequenses then no problem go ahead.

Putting it all together:

mp3Table_mt = 
{
    __tostring = function(self)
        local ret = {}
        for k, v in ipairs(self) do
            table.insert(ret, v[1] .. "\t" .. v[2])
        end
        return table.concat(ret, "\n")
    end
}

function addSongList(mp3Table)
    local load_dialog = createOpenDialog(self)
    load_dialog.InitalDir = os.getenv('%USERPROFILE%')
    load_dialog.Filter = 'MP3 files|*.mp3|*'
    load_dialog.execute()
    file = load_dialog.FileName
    if file then
        --- parsing path and filename
        local pathN = file:match("(.*[\\/])")
        local path, name = file:match('(.*\\)(.*)%.mp3')
        --- test  to open E:\MyMP3\mysong.mp3
        print(pathN)   --- result : E:\MyMP3\
        print(name)    --- result : mysong.mp3
        table.insert(mp3Table,{pathN,name})
    end

    return mp3Table
end

function clearTable(tb)
    for i, v in pairs(tb) do
        tb[i] = nil
    end
end

local mp3Table = setmetatable({}, mp3Table_mt)

print(addSongList(mp3Table))

clearTable(mp3Table) -- I'm not assigning a new one. Just clearing the fields.

print(mp3Table) -- Must print nothing
Eric Chiesse
  • 455
  • 3
  • 8
  • Thank you so much @Eric Chiesse for clearly explanations. Now, I understood how it work, mainly to empty a lua table. – JoeFern Feb 28 '18 at 04:58
  • @user3670853 NP friend :D. If you find the answer useful could you upvote it? Anyhow hope your problem is solved. All good to you – Eric Chiesse Mar 06 '18 at 21:44
0

1)yes

2)printing table in cycle:

for k,v in pairs(mp3Table) do
 print( v.pathN, v.name)
end

3)empty table

mp3Table = {}     --  clean 
mp3Table = nil    --  delete
Mike V.
  • 2,077
  • 8
  • 19
  • actually to clear/empty a table you would rather do `mp3Table = {}`. Otherwise you don't end up with an empty table but with a nil value. – Piglet Feb 23 '18 at 07:19
  • @user3670853 you need use `table.insert` inside function `addSongList()` – Mike V. Feb 23 '18 at 10:08
  • Thank you @Mike V., since item (pathN, name) not added to mp3Table maybe because CE Lua environment, then I am use : 'mp3Table[a+1] = file', which 'a' is number of table length which I get with a function and yes I have move 'table.insert' inside 'addSongList()'. – JoeFern Feb 23 '18 at 16:14