Comment puis-je obtenir le nombre de clés dans une table de hachage dans Lua?

StackOverflow https://stackoverflow.com/questions/652957

  •  19-08-2019
  •  | 
  •  

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
Était-ce utile?

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

L'opérateur de longueur:

  

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

Exemple de travail en direct

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 () .

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top