Как получить количество записей в таблице Lua? - PullRequest
114 голосов
/ 24 апреля 2010

Звучит как вопрос "дай мне Google для тебя", но почему-то я не могу найти ответ. Оператор Lua # считает только записи с целочисленными ключами, как и 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"

Как я могу получить количество всех записей, не считая их?

Ответы [ 7 ]

110 голосов
/ 24 апреля 2010

У вас уже есть решение вопроса - единственный способ - перебрать всю таблицу с помощью pairs(..).

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

Также обратите внимание, что определение оператора "#" немного сложнее, чем это. Позвольте мне проиллюстрировать это, взяв эту таблицу:

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

Согласно руководству, любой из 3, 5 и 9 является действительным результатом для #t. Единственный разумный способ его использования - с массивами из одной смежной части без нулевых значений.

19 голосов
/ 24 апреля 2010

Вы можете настроить мета-таблицу для отслеживания количества записей, это может быть быстрее, чем итерация, если эта информация часто нужна.

2 голосов
/ 01 июля 2019

Вы можете использовать библиотеку ручек . У него есть функция size, которая дает фактический размер таблицы.

В нем реализовано множество функций, которые могут нам понадобиться при программировании и отсутствовать в Lua.

Вот пример использования.

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

> #a
0

> tablex.size(a)
3
1 голос
/ 02 ноября 2017

Самый простой способ узнать количество записей в таблице - использовать '#'. #tableName возвращает количество записей, если они пронумерованы:

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

К сожалению, если они не пронумерованы, это не сработает.

1 голос
/ 09 мая 2016
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 голос
/ 25 апреля 2010

Есть один способ, но он может разочаровать: использовать дополнительную переменную (или одно из полей таблицы) для хранения счетчика и увеличивать его каждый раз, когда вы делаете вставку.

count = 0
tbl = {}

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

tbl[1] = 48
count = count + 1

print(count)   -- prints "2"

Другого пути нет, оператор # будет работать только с массивными таблицами с последовательными ключами.

0 голосов
/ 25 октября 2017

появляется, когда элементы таблицы добавляются методом вставки, getn вернется правильно. В противном случае мы должны считать все элементы

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

Он напечатает 2 правильно

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...