Come posso ottenere il numero di chiavi in ??una tabella hash in Lua?
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
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
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
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 () .