非数字索引和#从不计算?

时间:2014-10-28 11:41:34

标签: lua indexing lua-table

给出一个包含混合索引的表,如:

table = {
  foo = 'bar'
  [1] = 'foobar'
}

我的问题是#给出了最后一个索引,它在迭代表格时没有通过间隙分开。

print(#table) 

将输出 1

table = {
  foo = 'bar',
  lol = 'rofl',
  [1] = 'some',
  [2] = 'thing',
  [3] = 'anything',
  [4] = 'else'
}
print(#table)

应打印 4

我能100%确定#永远不会被非数字索引分散注意力吗? 这些指数是否每次都被忽视?

3 个答案:

答案 0 :(得分:3)

是的,你可以指望(在lua 5.1中)。

来自lua reference manual

  

长度运算符由一元运算符#表示。的长度   字符串是它的字节数(也就是字符串的通常含义)   每个字符为一个字节时的长度。)

     

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

lua 5.2允许__len元方法对表进行操作,这意味着#可以执行其他操作。有关示例,请参阅@ kikito的答案。

答案 1 :(得分:2)

Etan的答案是正确的,但不完整。

在Lua中,如果表格的metatable具有__len函数,它将控制#运算符吐出的内容。可以定义它,以便它考虑非数组键。

local mt = {__len = function(tbl)
  local len = 0
  for _ in pairs(tbl) do len = len + 1 end
  return len
end}

这表明了事情:

local t = {1,2,3,4,foo='bar',baz='qux'}

print(#t) -- 4
setmetatable(t, mt)
print(#t) -- 6

如果您确实想要确保您获得正确的"类似于数组的长度,您必须使用rawlen代替:

print(rawlen(t)) -- 4, even with the metatable set

编辑:请注意__len不能像我在Lua 5.1上提到的那样工作

答案 2 :(得分:0)

唯一的方法是遍历条目并计算它们。通过项目迭代ipair并递增计数器然后返回结果。

function tablelength(T)
 local count = 0 for _ in pairs(T) do
    count = count + 1 end
 return count 
end

#运算符仅适用于哈希表类型。

请参阅:How to get number of entries in a Lua table?