web-dev-qa-db-fra.com

Comment obtenir le nombre d'entrées dans une table Lua?

Cela ressemble à une question "laissez-moi google pour vous", mais de toute façon je ne trouve pas de réponse. L'opérateur Lua # ne compte que les entrées avec des clés entières, de même que table.getn:

tbl = {}
tbl["test"] = 47
tbl[1] = 48
print(#tbl, table.getn(tbl))   -- prints "1     1"

count = 0
for _ in pairs(tbl) do count = count + 1 end
print(count)            -- prints "2"

Comment puis-je obtenir le nombre de toutes entrées sans les compter?

105
Roman Starkov

Vous avez déjà la solution à la question - le seul moyen est d’itérer toute la table avec pairs(..).

function tablelength(T)
  local count = 0
  for _ in pairs(T) do count = count + 1 end
  return count
end

Notez également que la définition de l'opérateur "#" est un peu plus compliquée que cela. Permettez-moi d'illustrer cela en prenant ce tableau:

t = {1,2,3}
t[5] = 1
t[9] = 1

Selon le manuel, l'un des 3, 5 et 9 sont des résultats valides pour #t. La seule façon sensée de l'utiliser est d'utiliser des tableaux d'une partie contiguë sans valeurs nil. 

102
u0b34a0f6ae

Vous pouvez configurer une méta-table pour suivre le nombre d'entrées. Cela peut être plus rapide que l'itération si cette information est fréquemment nécessaire. 

19
ergosys

Il y a un moyen, mais cela peut être décevant: utilisez une variable supplémentaire (ou un champ de la table) pour stocker le nombre, et augmentez-le chaque fois que vous faites une insertion.

count = 0
tbl = {}

tbl["test"] = 47
count = count + 1

tbl[1] = 48
count = count + 1

print(count)   -- prints "2"

Il n'y a pas d'autre moyen, l'opérateur # ne travaillera que sur des tables de type tableau avec des clés consécutives.

2
kikito

Vous pouvez utiliser bibliothèque de penlight . Cela a une fonction size qui donne la taille réelle de la table.

Il a mis en œuvre de nombreuses fonctions dont nous pourrions avoir besoin lors de la programmation et manquantes dans Lua.

Voici l'exemple pour l'utiliser.

> tablex = require "pl.tablex"
> a = {}
> a[2] = 2
> a[3] = 3 
> a['blah'] = 24

> #a
0

> tablex.size(a)
3
2
user11464249

Le moyen le plus simple que je connaisse pour obtenir le nombre d'entrées dans une table est avec '#'. #tableName obtient le nombre d'entrées pourvu qu'elles soient numérotées:

tbl={
    [1]
    [2]
    [3]
    [4]
    [5]
}
print(#tbl)--prints the highest number in the table: 5

Malheureusement, s'ils ne sont pas numérotés, cela ne fonctionnera pas.

2
Surge12
local function CountedTable(x)
    assert(type(x) == 'table', 'bad parameter #1: must be table')

    local new_t = {}
    local mt = {}

    -- `all` will represent the number of both
    local all = 0
    for k, v in pairs(x) do
        all = all + 1
    end

    mt.__newindex = function(t, k, v)
        if v == nil then
            if rawget(x, k) ~= nil then
                all = all - 1
            end
        else
            if rawget(x, k) == nil then
                all = all + 1
            end
        end

        rawset(x, k, v)
    end

    mt.__index = function(t, k)
        if k == 'totalCount' then return all
        else return rawget(x, k) end
    end

    return setmetatable(new_t, mt)
end

local bar = CountedTable { x = 23, y = 43, z = 334, [true] = true }

assert(bar.totalCount == 4)
assert(bar.x == 23)
bar.x = nil
assert(bar.totalCount == 3)
bar.x = nil
assert(bar.totalCount == 3)
bar.x = 24
bar.x = 25
assert(bar.x == 25)
assert(bar.totalCount == 4)
1
Sleepwom

semble que lorsque les éléments de la table sont ajoutés par la méthode insert, getn retournera correctement. Sinon, nous devons compter tous les éléments

mytable = {}
element1 = {version = 1.1}
element2 = {version = 1.2}
table.insert(mytable, element1)
table.insert(mytable, element2)
print(table.getn(mytable))

Il imprimera 2 correctement

0
Yongxin Zhang