Pregunta

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

¿Realmente tengo que recorrer los elementos de la tabla para obtener el número de claves?

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

Solución

Experimenté con el operador # y table.getn (). Pensé que table.getn () haría lo que quisieras, pero resulta que devuelve el mismo valor que #, es decir, 0. Parece que los diccionarios insertan marcadores de posición nulos según sea necesario.

Recorrer las teclas y contarlas parece ser la única forma de obtener el tamaño del diccionario.

Otros consejos

El operador de longitud:

  

La longitud de una tabla t se define como cualquier índice entero n tal que t [n] no es nulo y t [n + 1] es nulo; además, si t [1] es nulo, n puede ser cero. Para una matriz regular, con valores no nulos de 1 a un n dado, su longitud es exactamente ese n, el índice de su último valor. Si la matriz tiene " agujeros " (es decir, valores nulos entre otros valores no nulos), entonces #t puede ser cualquiera de los índices que preceden directamente a un valor nulo (es decir, puede considerar cualquier valor nulo como el final de la matriz).

así que la única forma de obtener longitud es iterar sobre ella.

Además de iterar a través de las teclas manualmente, es sencillo realizar un seguimiento automático a través de metametodos. Teniendo en cuenta que probablemente no desee realizar un seguimiento de cada tabla que haga, simplemente puede escribir una función que le permitirá convertir cualquier tabla en un objeto contable por clave. Lo siguiente no es perfecto, pero creo que ilustraría el punto:

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

Ejemplos de uso de esto incluirían:

-- 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

Ejemplo de trabajo en vivo

¡Espero que esto haya ayudado! :)

Lua almacena la tabla como dos partes separadas: una parte hash y una parte de matriz, el operador len solo trata con la parte de matriz, es decir, el valor indexado por un valor numérico, además de usar las reglas mencionadas a continuación, para que no tenga ninguna elección para contar '' hash '' valor que necesita iterar sobre la tabla con la función pares () .

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top