[lua] How to get number of entries in a Lua table?

Sounds like a "let me google it for you" question, but somehow I can't find an answer. The Lua # operator only counts entries with integer keys, and so does 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"

How do I get the number of all entries without counting them?

This question is related to lua

The answer is


You could use penlight library. This has a function size which gives the actual size of the table.

It has implemented many of the function that we may need while programming and missing in Lua.

Here is the sample for using it.

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

> #a
0

> tablex.size(a)
3

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)

The easiest way that I know of to get the number of entries in a table is with '#'. #tableName gets the number of entries as long as they are numbered:

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

Sadly, if they are not numbered, it won't work.


You can set up a meta-table to track the number of entries, this may be faster than iteration if this information is a needed frequently.


I stumbled upon this thread and want to post another option. I'm using Luad generated from a block controller, but it essentially works by checking values in the table, then incrementing which value is being checked by 1. Eventually, the table will run out, and the value at that index will be Nil.

So subtract 1 from the index that returned a nil, and that's the size of the table.

I have a global Variable for TableSize that is set to the result of this count.

function Check_Table_Size()
  local Count = 1
  local CurrentVal = (CueNames[tonumber(Count)])
  local repeating = true
  print(Count)
  while repeating == true do
    if CurrentVal ~= nil then
      Count = Count + 1
      CurrentVal = CueNames[tonumber(Count)]
     else
      repeating = false
      TableSize = Count - 1
    end
  end
  print(TableSize)
end

seems when the elements of the table is added by insert method, getn will return correctly. Otherwise, we have to count all elements

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

It will print 2 correctly


There's one way, but it might be disappointing: use an additional variable (or one of the table's field) for storing the count, and increase it every time you make an insertion.

count = 0
tbl = {}

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

tbl[1] = 48
count = count + 1

print(count)   -- prints "2"

There's no other way, the # operator will only work on array-like tables with consecutive keys.


function GetTableLng(tbl)
  local getN = 0
  for n in pairs(tbl) do 
    getN = getN + 1 
  end
  return getN
end

You're right. There are no other way to get length of table