Como faço para obter o número de chaves em uma tabela hash na Lua?
Pergunta
myTable = {}
myTable["foo"] = 12
myTable["bar"] = "blah"
print(#myTable) -- this prints 0
Do eu realmente tenho que percorrer os itens da tabela para obter o número de chaves?
numItems = 0
for k,v in pairs(myTable) do
numItems = numItems + 1
end
print(numItems) -- this prints 2
Solução
Eu experimentei com o operador # e table.getn (). Pensei table.getn () iria fazer o que você queria, mas como se vê ele está retornando o mesmo valor #, ou seja 0. Parece que os dicionários inserir espaços reservados nil como necessário.
looping sobre as teclas e contá-las parece ser a única maneira de obter o tamanho do dicionário.
Outras dicas
O comprimento de uma tabela t é definido como qualquer índice inteiro n tal que t [n] não é nula e t [n + 1] é nil; Além disso, se t [1] é igual a zero, n pode ser zero. Para uma matriz regular, com valores diferentes de nil de 1 a um dado n, seu comprimento é exatamente o que n, o índice do seu último valor. Se a matriz tem "furos" (isto é, valores nulos entre outros valores não nulos), então #t pode ser qualquer um dos índices que precede directamente um valor nulo (isto é, pode considerar qualquer valor nil como a extremidade da matriz).
comprimento tão única maneira de obter é iterar sobre ele.
Além de iteração através das teclas manualmente, é simples para manter automaticamente a trilha dele via metamétodos. Considerando que você provavelmente não quer manter o controle de cada mesa que você faz, você pode apenas escrever uma função que lhe permitirá converter qualquer tabela em um objeto-chave contáveis. O seguinte não é perfeito, mas eu acho que seria ilustrar o ponto:
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
Exemplos da utilização deste incluem:
-- 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
Espero que isso ajudou! :)
Lua armazena tabela como peças dois separa: a parte de hash e uma parte array, o operador len lidar apenas com a parte de matriz, ou seja, o valor indexado por um valor numérico, mais usando as regras a seguir mencionadas, para que você não tem qualquer escolha para a contagem de valor "hash de" você precisa iterar sobre a mesa com pares () função.