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
Foi útil?

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 operador de tamanho:

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

Vivo Exemplo de Trabalho

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.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top