Domanda

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

Devo effettivamente scorrere gli elementi nella tabella per ottenere il numero di chiavi?

numItems = 0
for k,v in pairs(myTable) do
    numItems = numItems + 1
end
print(numItems) -- this prints 2
È stato utile?

Soluzione

Ho sperimentato sia l'operatore # sia table.getn (). Ho pensato che table.getn () avrebbe fatto quello che volevi, ma a quanto pare sta restituendo lo stesso valore di #, vale a dire 0. Sembra che i dizionari inseriscano nulli segnaposto se necessario.

Ripassare i tasti e contarli sembra l'unico modo per ottenere le dimensioni del dizionario.

Altri suggerimenti

L'operatore di lunghezza:

  

La lunghezza di una tabella t è definita come qualsiasi indice intero n tale che t [n] non sia nullo e t [n + 1] sia nullo; inoltre, se t [1] è zero, n può essere zero. Per un array normale, con valori diversi da 1 a un dato n, la sua lunghezza è esattamente quella n, l'indice del suo ultimo valore. Se l'array ha "fori" (ovvero valori nulli tra altri valori diversi da zero), quindi #t può essere uno qualsiasi degli indici che precede direttamente un valore nullo (vale a dire, può considerare qualsiasi valore nullo come la fine dell'array).

quindi l'unico modo per ottenere la lunghezza è iterare su di esso.

Oltre a scorrere manualmente i tasti, è semplice tenerne traccia automaticamente tramite metametodi. Considerando che probabilmente non vuoi tenere traccia di ogni tabella che crei, puoi semplicemente scrivere una funzione che ti permetterà di convertire qualsiasi tabella in un oggetto numerabile da chiave. Quanto segue non è perfetto, ma penso che illustrerebbe il 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

Esempi di utilizzo di questo includono:

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

Esempio di lavoro dal vivo

Spero che questo abbia aiutato! :)

Lua archivia la tabella come due parti separate: una parte hash e una parte array, l'operatore len si occupa solo della parte array, ovvero valore indicizzato da un valore numerico, oltre a utilizzare le regole menzionate di seguito, quindi non si hanno scelta per il conteggio "hash" valore che devi scorrere sulla tabella con la funzione coppie () .

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top