9

I've embedded Lua into my C application, and am trying to figure out why a table created in my C code via:

lua_createtable(L, 0, numObjects);

and returned to Lua, will produce a result of zero when I call the following:

print("Num entries", table.getn(data))

(Where "data" is the table created by lua_createtable above)

There's clearly data in the table, as I can walk over each entry (string : userdata) pair via:

for key, val in pairs(data) do
  ...
end

But why does table.getn(data) return zero? Do I need to insert something into the meta of the table when I create it with lua_createtable? I've been looking at examples of lua_createtable use, and I haven't seen this done anywhere....

jimt
  • 1,980
  • 2
  • 21
  • 28

4 Answers4

24

table.getn (which you shouldn't be using in Lua 5.1+. Use the length operator #) returns the number of elements in the array part of the table.

The array part is every key that starts with the number 1 and increases up until the first value that is nil (not present). If all of your keys are strings, then the size of the array part of your table is 0.

Nicol Bolas
  • 449,505
  • 63
  • 781
  • 982
  • Is there no easy way to do what I'm trying to do, then? -- Get the number of elements (read pairs) in the table I have without iterating over it directly? – jimt Mar 08 '12 at 06:20
  • 1
    You can manually keep track of the table size whenever you change something to the table and overload the `__len` metamethod to have operator # return that value. Of course this approach requires a lot of coding discipline - forget updating the table size value and you're screwed. – ComicSansMS Mar 08 '12 at 07:41
  • 4
    It's rude to say "use the length operator #" and not mention an example. What this answer is saying is, "To get the length of an array A, type #A". It may seem trivial but it's a thing that throws many people off and causes doubt as you can't assume an operator behaves the way you think it does until you have tested and became comfortable with it. Upvoted nonetheless. – Dmytro Jul 20 '16 at 18:08
3

Although it's a costly (O(n) vs O(1) for simple lists), you can also add a method to count the elements of your map :

>> function table.map_length(t)
    local c = 0
    for k,v in pairs(t) do
         c = c+1
    end
    return c
end

>> a = {spam="data1",egg='data2'}
>> table.map_length(a)
2

If you have such requirements, and if your environment allows you to do so think about using penlight that provides that kind of features and much more.

Jocelyn delalande
  • 5,123
  • 3
  • 30
  • 34
2

the # operator (and table.getn) effectivly return the size of the array section (though when you have a holey table the semantics are more complex)

It does not count anything in the hash part of the table (eg, string keys)

daurnimator
  • 4,091
  • 18
  • 34
0
for k,v in pairs(tbl) do count = count + 1 end
skuntsel
  • 11,624
  • 11
  • 44
  • 67
Max
  • 11
  • 1