【问题标题】:how to delete all elements in a Lua table?如何删除 Lua 表中的所有元素?
【发布时间】:2011-06-20 07:18:05
【问题描述】:

如何删除 Lua 表中的所有元素?我不想这样做:

t = {}
table.insert(t, 1)
t = {}  -- this assigns a new pointer to t

我想保留指向 t 的相同指针,但删除 t 中的所有元素。

我试过了:

t = {}
table.insert(t, 1)
for i,v in ipairs(t) do table.remove(t, i) end

以上内容有效吗?还是需要其他东西?

【问题讨论】:

  • 我猜情况是在一个函数中清空一个表,把它作为参数。那么这个问题很好,+1。起初我对“指针”这个词感到困惑,它存在于 c 代码中,不应该在 Lua 代码中提及。你的意思是“参考”什么的。

标签: lua lua-table


【解决方案1】:
for k in pairs (t) do
    t [k] = nil
end

也可以使用 - 如果表格始终不用作数组,您可能无法使用 ipairs。

【讨论】:

    【解决方案2】:

    表格元素插入和删除 性能比较

    表大小计数 10000000

    [1] while 和 rawset

    while #t ~= 0 do rawset(t, #t, nil) end
    

    花费时间 = 0.677220

    [2] 下一个和原始集

    for k in next, t do rawset(t, k, nil) end
    

    花费时间 = 0.344533

    [3] ipairs 和 rawset

    for i, v in ipairs(t) do t[i] = nil end
    

    花费时间 = 0.012450

    [4] 为,原始集

    count = #t
    for i=0, count do t[i]=nil end
    

    花费时间 = 0.009308

    表格元素插入

    [1]表格插入函数

    for i=0, 10000000 do    table.insert(t, i, i) end
    

    花费时间 = 1.0590489

    [2] 使用#t

    for i=0, 10000000 do    t[#t+1] = i end
    

    花费时间 = 0.703731

    [3] 为,原始集

    for i=0, 10000000 do rawset(t, i, i) end
    

    花费时间 = 0.100010

    结果。

    最快移除:4

    最快插入:3

    【讨论】:

    • 这是一个彻底而有效的答案。
    【解决方案3】:

    最简单、最高效:

    for k,v in pairs(tab) do tab[k]=nil end
    

    您的建议不可用:table.remove 移动其余元素以关闭孔,从而弄乱了表遍历。有关更多信息,请参阅the next function 的说明

    【讨论】:

      【解决方案4】:

      对于忽略__pairs 元方法的更快版本:

      local next = next
      local k = next(tab)
      while k ~= nil do
        tab[k] = nil
        k = next(tab, k)
      end
      

      编辑:正如@siffiejoe 在 cmets 中提到的,这可以通过将 pairs 调用替换为其默认的表返回值来简化为 for 循环:next 方法和表本身。此外,为避免所有元方法,请使用rawset 方法进行表索引分配:

      for k in next, tab do rawset(tab, k, nil) end
      

      【讨论】:

      • 或者只是for k in next,tab do tab[k] = nil end
      • 根据lua.org/gems/sample.pdf(一个Lua优化指南),这个方法出奇的可怕。问题在于将元素设置为 nil 通常不会将其从表中删除,直到下一次调整大小。 next 的实现必须在返回之前搜索所有的 nil,这使得这令人惊讶 O(n^2)。
      • @AHelps 感谢您指出这一点!我更长的while 版本不会受到此影响,因为next 是用以前的索引调用的。 @siffiejoe 的版本缺少那部分,所以它是慢版本。我将对答案进行解释性编辑。
      • @AHelps 实际上,我收回了这一点:“通用for 循环”构造自动将迭代器函数的返回值作为下一次迭代中函数的第二个参数。所以第一次迭代是k = next(tab, nil),但是下一次迭代是k = next(tab, k),这样就避免了全遍历。
      【解决方案5】:

      #table 是表大小,所以如果t = {1,2,3}#t = 3

      因此您可以使用此代码删除元素

      while #t ~= 0 do rawset(t, #t, nil) end

      您将遍历表格并删除每个元素,最后得到一个空表格。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2013-04-06
        • 1970-01-01
        • 1970-01-01
        • 2013-12-02
        • 2021-06-16
        • 2013-10-02
        • 1970-01-01
        相关资源
        最近更新 更多