确定Lua表是否为空(不包含任何条目)的最有效方法是什么?

确定Lua表是否为空(不包含任何条目)的最有效方法是什么?,lua,lua-table,Lua,Lua Table,确定表是否为空(即当前既不包含数组样式值也不包含dict样式值)的最有效方法是什么 目前,我正在使用next(): 有没有更有效的方法 注意:#运算符在这里不够,因为它只对表中的数组样式值进行操作-因此#{test=2}与#{}无法区分,因为两者都返回0。还请注意,检查表变量是否为nil是不够的,因为我不是在查找nil值,而是查找具有0个条目的表(即{})。一种可能是使用元表“newindex”键来计算元素的数量。分配非nil的内容时,增加计数器(计数器也可以存在于元表中),分配nil时,减少计

确定表是否为空(即当前既不包含数组样式值也不包含dict样式值)的最有效方法是什么

目前,我正在使用
next()

有没有更有效的方法


注意:
#
运算符在这里不够,因为它只对表中的数组样式值进行操作-因此
#{test=2}
#{}
无法区分,因为两者都返回0。还请注意,检查表变量是否为
nil
是不够的,因为我不是在查找nil值,而是查找具有0个条目的表(即
{}
)。

一种可能是使用元表“newindex”键来计算元素的数量。分配非
nil
的内容时,增加计数器(计数器也可以存在于元表中),分配
nil
时,减少计数器

测试空表将是使用0测试计数器

这里有一个指向


不过,我确实喜欢您的解决方案,老实说,我不能假设我的解决方案总体上更快。

您的代码是有效的,但却是错误的。(考虑
{[false]=0}
)正确的代码是

if next(myTable) == nil then
   -- myTable is empty
end
为了获得最大效率,您需要将
next
绑定到局部变量,例如

...
local next = next 
...
... if next(...) ...

这可能是您想要的:

输出:

true
假的
真的

我知道这很旧,我可能会误解你,但如果你只是想让表为空,也就是说,除非你只是检查它是否为空,并且你实际上不想或不需要它为空,你可以通过简单地重新创建它来清除它,除非我弄错了。这可以通过以下语法完成

yourtablename = {} -- this seems to work for me when I need to clear a table.
尝试使用
#
。它返回表中的所有实例。如果表中没有实例,则返回
0

if #myTable==0 then
print('There is no instance in this table')
end

如果过载,最好避免对_eq进行评估

if rawequal(next(myTable), nil) then
   -- myTable is empty
end


试试蛇,为我工作

serpent = require 'serpent'

function vtext(value)
  return serpent.block(value, {comment=false})
end

myTable = {}

if type(myTable) == 'table' and vtext(myTable) == '{}' then
   -- myTable is empty
end
这个怎么样

if endmyTable[1] == nil then
  -- myTable is empty
end

技术正确性方面的良好观点;在我使用原始代码的特定情况下,
false
将不是期望的键,因此
如果不
工作得很好,但我可能会在将来养成一个习惯,将其与
nil
进行比较,这也是一个好习惯。是的,为了提高速度,我已经将公共实用程序函数绑定到本地变量。感谢您的输入。当代码按预期工作时,我很难同意错误。为什么我们通过执行
local next
?@Moberg来提高速度?这是由于LUA如何处理其名称空间。非常简单的版本是,它将首先爬升本地表,因此如果当前块中存在
local next
,它将使用它,然后爬升到下一个块,并重复。一旦退出局部变量,它将只使用全局名称空间。这是它的一个简化版本,但最终,它肯定意味着程序速度的不同。@Moberg在运行时,全局变量需要哈希表查找,而局部变量只需要数组查找。最初的问题不是只计算“数组”0x6的建议并不特定于数组样式的条目(newindex适用于数字和非数字索引)。但是,主要问题是检测何时分配了
nil
,因为如果表中已经存在键,则不会触发uu newindex。要使此技巧起作用,元表必须同时实现
\uu index
\uu newindex
,将实际数据存储在阴影表中,并将实际表保持为空,以便调用
\u index
。大声想想,我怀疑每一次查找所增加的成本都不值得。
next()
比循环
pairs()
更高效(更简洁)。事实上,循环
pairs()
基本上只是使用
next()
技术,但开销更大。此外,不建议写入标准的
库。这不是问题。询问者说
#
在这里不够,并给出了原因;你能解释一下为什么会绕开这些原因吗?嗯……我不知道。我是这方面的新手,所以我知道的唯一方法是使用#
#
仅适用于从索引
1开始的连续数组。以下表格不起作用:
{a=true}
{[2]=true}
。这对作为索引的字符串的表格或索引
1
处没有值的表格不起作用。考虑<代码> { 2〕=真} /代码>我是LuaNob,试图理解为什么这个答案被否决了。我猜这是因为在Lua中,“如果两个对象有不同的元方法,相等操作会导致false,甚至不会调用任何元方法”。(报价在本页底部)。这是否消除了避免nil的eq过载的需要?
if type(next(myTable)) == "nil" then
   -- myTable is empty
end
serpent = require 'serpent'

function vtext(value)
  return serpent.block(value, {comment=false})
end

myTable = {}

if type(myTable) == 'table' and vtext(myTable) == '{}' then
   -- myTable is empty
end
if endmyTable[1] == nil then
  -- myTable is empty
end