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

时间:2009-03-17 03:40:56

标签: lua hashtable

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

4 个答案:

答案 0 :(得分:21)

我尝试使用#运算符和table.getn()。我认为table.getn()可以做你想要的,但事实证明它返回与#相同的值,即0。看起来字典会根据需要插入nil占位符。

循环键并计算它们似乎是获取字典大小的唯一方法。

答案 1 :(得分:7)

The length operator:

  

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

所以只有获得长度的方法就是迭代它。

答案 2 :(得分:4)

除了手动迭代键之外,通过元方法自动跟踪它很简单。考虑到您可能不希望跟踪所制作的每个表,您只需编写一个函数,允许您将任何表转换为可计数键的对象。以下并不完美,但我认为这将说明一点:

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

Live Working Example

希望这有帮助! :)

答案 3 :(得分:1)

Lua将表存储为两个分开的部分:散列部分和数组部分,len运算符只处理数组部分,意味着由数值索引的值,加上使用下面提到的规则,所以你没有任何选择计算“哈希”值,你需要使用对()函数迭代表。