如何在Lua中获取哈希表中键的数量?

47
myTable = {}
myTable["foo"] = 12
myTable["bar"] = "blah"
print(#myTable) -- this prints 0

我是否真的需要迭代表格中的项才能获取键的数量?

numItems = 0
for k,v in pairs(myTable) do
    numItems = numItems + 1
end
print(numItems) -- this prints 2

如何获取Lua表中条目数量?相同的问题。 - user202729
4个回答

23

我尝试了#操作符和table.getn()函数。我认为table.getn()函数能够满足你的需求,但是事实证明它返回的值与#相同,即0。看起来字典会根据需要插入nil占位符。

循环遍历键并计数似乎是获取字典大小的唯一方法。


print(table.getn(myTable)) 这会输出 0。 - Jay
3

是指 table.getn 的简写,因此您将获得相同的结果。

- serioys sam
澄清一下,#tbl 将返回表 tbl 的长度。 - Daniel Morris
3
进一步澄清一下,#tbl会计算条目数,直到找到空键为止。它仅适用于常规(非稀疏)数组,即在这种情况下,您有tbl [1],tbl [2]等,没有删除或空条目。 - James Anderson
2
有点遗憾,table 命名空间中没有这样的方法。 - polemon

8

长度运算符:

表t的长度被定义为任何整数索引n,使得t[n]不是nil且t[n+1]是nil;此外,如果t[1]是nil,则n可以为零。对于一个常规数组,其非nil值从1到给定的n,其长度恰好是n,即其最后一个值的索引。如果数组中有“空洞”(即在其他非nil值之间的nil值),则#t可以是直接在nil值之前的任何索引(即,它可以将任何这样的nil值视为数组的结尾)。

因此,唯一获取长度的方法是迭代。


5

除了手动迭代键值外,通过元方法自动跟踪键值也很简单。考虑到您可能不想跟踪每一个创建的表格,您可以编写一个函数,将任何表格转换为可计数的对象。以下代码并不完美,但我认为它可以说明问题:

function CountedTable(x)
  assert(type(x) == 'table', 'bad parameter #1: must be table')

  local mt = {}
  -- `keys`  will represent the number of non integral indexes
  -- `indxs` will represent the number of integral indexes
  -- `all`   will represent the number of both 
  local keys, indxs, all = 0, 0, 0

  -- Do an initial count of current assets in table. 
  for k, v in pairs(x) do
    if (type(k) == 'number') and (k == math.floor(k)) then indxs = indxs + 1
    else keys = keys + 1 end

    all = all + 1
  end

  -- By using `__nexindex`, any time a new key is added, it will automatically be
  -- tracked.
  mt.__newindex = function(t, k, v)
    if (type(k) == 'number') and (k == math.floor(k)) then indxs = indxs + 1
    else keys = keys + 1 end

    all = all + 1
    t[k] = v
  end

  -- This allows us to have fields to access these datacounts, but won't count as
  -- actual keys or indexes.
  mt.__index = function(t, k)
    if k == 'keyCount' then return keys 
    elseif k == 'indexCount' then return indxs 
    elseif k == 'totalCount' then return all end
  end

  return setmetatable(x, mt)
end

使用此功能的示例包括:
-- Note `36.35433` would NOT be counted as an integral index.
local foo = CountedTable { 1, 2, 3, 4, [36.35433] = 36.35433, [54] = 54 }
local bar = CountedTable { x = 23, y = 43, z = 334, [true] = true }
local foobar = CountedTable { 1, 2, 3, x = 'x', [true] = true, [64] = 64 }

print(foo.indexCount)    --> 5
print(bar.keyCount)      --> 4
print(foobar.totalCount) --> 6

现场工作示例

希望这有所帮助!:)


1
无法跟踪键的删除。 - Timothy003
1
当然可以。你只需要使用__index__newindex添加一个间接层级即可。 - Qix - MONICA WAS MISTREATED

1
Lua将表存储为两个独立的部分:哈希部分和数组部分,len运算符仅处理数组部分,即由数字值索引的值,并使用下面提到的规则,因此您没有任何选择来计算“哈希”值,您需要使用pairs()函数迭代表。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接