1

我使用 Lua 作弊引擎创建了一个从计算机目录解析路径名和文件名的函数,接下来我想将结果存储到 Lua 表中。

我的功能:

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. 这是使用 table.insert(mp3Table,{pathN,name}) 的正确方法和正确语法吗
  2. 如何通过打印出来检查元素是否已经添加到表格中?
  3. 如何清空/清空表?

谢谢

4

2 回答 2

1

1 - 插入表格:

table.insert(tb, value)插入valueto de 表tb。使用table.insert(mp3Table,{pathN,name})您动态创建一个(子)表,然后附加到主表。

2 - 打印表格。

正如已经指出的那样,您可以使用pairsor遍历表ipairs以获取元素。在这种情况下,我更喜欢 ipairs,因为该表是数字索引的,并且按照 table.insert 保证顺序。内表必须按数字索引,因为您使用数字索引创建了它。

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

但是你也可以选择一个元表,它也可以让你为表生成一个字符串表示:

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
}

初始化时mp3Table,您必须分配元表

local mp3Table = setmetatable({}, mp3Table_mt)

然后你可以告诉 Lua 打印表格:

print(mp3Table)

3 - 清空/删除表:

那么这里有两个不同的东西。一个是空的,另一个是删除。

Lua 使用垃圾回收,因此只有在不再引用特定表时才会发生实际删除。告诉 Lua 你不再需要一个变量,你可以做的是给它赋值 nil。如果没有其他对变量指向的值的引用,GC 将在运行时清理它。

但是您可以清空表而不删除它。说mp3Table = {}“清空桌子”可能很诱人。但事实并非如此。在这种情况下,您正在做的是将一个新的表分配给mp3Table变量。如果任何其他变量仍然指向旧表,它将不会被收集,并且内部值将保持不变。如果没有这样的其他变量,则该表将被垃圾收集,就像您分配nilmp3Table变量一样。

因此,要有效地清空表,您必须遍历它并将其所有变量设置为 nil。

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

特别是在所问的情况下,只需为 mp3Table 分配一个新表就足够了,因为没有更多对同一个表的引用。之后分配 nil 是不必要的。重要的是是否有变量指向相同的值。如果您知道自己在做什么以及后果,那么就没有问题了。

把它们放在一起:

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
于 2018-02-24T20:15:20.320 回答
0

1)是的

2)循环打印表格:

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

3)空表

mp3Table = {}     --  clean 
mp3Table = nil    --  delete
于 2018-02-23T06:58:53.557 回答