Comment puis-je obtenir le nombre de clés dans une table de hachage dans Lua?
Question
myTable = {}
myTable["foo"] = 12
myTable["bar"] = "blah"
print(#myTable) -- this prints 0
Dois-je réellement parcourir les éléments de la table pour obtenir le nombre de clés?
numItems = 0
for k,v in pairs(myTable) do
numItems = numItems + 1
end
print(numItems) -- this prints 2
La solution
J'ai expérimenté à la fois l'opérateur # et table.getn (). Je pensais que table.getn () ferait ce que vous vouliez mais, comme il se trouve, il retourne la même valeur que #, à savoir 0. Il semble que les dictionnaires insèrent des espaces réservés nil si nécessaire.
Faire une boucle sur les clés et les compter semble être le seul moyen d'obtenir la taille du dictionnaire.
Autres conseils
La longueur d'une table t est définie comme tout indice entier n tel que t [n] ne soit pas nul et t [n + 1] soit nul; de plus, si t [1] est nul, n peut être zéro. Pour un tableau régulier, avec des valeurs non nuls de 1 à un n donné, sa longueur est exactement celle de n, l'indice de sa dernière valeur. Si le tableau comporte des "trous" (c’est-à-dire des valeurs nulles entre d’autres valeurs non nuls), alors #t peut être l’un des indices précédant directement une valeur nulle (c’est-à-dire qu’il peut considérer n'importe quelle valeur nulle comme la fin du tableau).
Le seul moyen d’obtenir de la longueur est donc de le parcourir.
Hormis l’itération manuelle des touches, il est simple de la suivre automatiquement via des métaméthodes. Considérant que vous ne voulez probablement pas garder une trace de chaque table que vous créez, vous pouvez simplement écrire une fonction qui vous permettra de convertir n'importe quelle table en un objet dénombrable par clé. Ce qui suit n’est pas parfait, mais je pense que cela illustrerait le propos:
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
Voici des exemples d'utilisation:
-- 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
J'espère que ça vous a aidé! :)
Lua stocke la table en deux parties distinctes: une partie de hachage et une partie de tableau, l’opérateur len ne traite que de la partie de tableau, c’est-à-dire une valeur indexée par une valeur numérique, plus l’utilisation des règles mentionnées ci-dessous, de sorte que vous n’en avez pas. choix pour compter & hash " valeur dont vous avez besoin pour parcourir la table avec la fonction pairs () .