some unexpected table length issues

hi there,

I am a fairly new lua developer, so please excuse me if I totally messed up something … but, here is my problem:

test code:

local t = {}  
t[1] = 10  
t[2] = 20  
t[3] = 30  
t[5] = 50   
  
print("table length is",#t)  

Console output:

table length is 3

Why? I expected it to be 4… Also If i replace t[5] = 50 with table.insert(t,5,50) nothing changes… Could you please explain me what is going on here? Thank you.

[import]uid: 11686 topic_id: 17796 reply_id: 317796[/import]

Well, you’re trying to add a fifth element to the table when there are only 3 there.

Changing t[5] = 50 to t[4] = 50 will work fine.

I’m not sure if you are after a technical answer as to why there must be a 4th to add a 5th or if you just wanted a way to fix the problem - if it’s the lesser please let me know and I’ll get you some more technical info.

Otherwise - that change will fix it.

Peach :slight_smile: [import]uid: 52491 topic_id: 17796 reply_id: 67923[/import]

I expected that lua tables behave like ordinary hash tables in other well known languages (like java or c#). official lua documentation clearly state that; “# operator gives element count of the table”… so it should be 4, i thought :). When i iterate the table (by using pairs) i could access those elements…

Isn’t that a bit weird? [import]uid: 11686 topic_id: 17796 reply_id: 67927[/import]

The length operator ‘#’ returns the intuitively-correct value only for
tables which are “arrays” (“sequences”, in the new Lua 5.2 parlance),
i.e. tables whose numeric keys begins at 1 and ends at some other
integer N. If there are “holes” or non integer numeric keys, ‘#’ returns
weird values, although its behaviour is well-defined in the manual [1]
(this behaviour was criticized and lead Lua Team to remove the
definition of ‘#’ for non-sequences in 5.2 and clarify the concept of
“array”, now formally called “sequences” in the manual [2]).

The same applies to ipairs (it will traverse an array only if *it is* an
“array”) and almost all other table library functions.

I tried to use table.getn( t ) aswell, but this doesn’t work neither.
I guess you’ll have to insert and delete using the table functions ( so there are no holes!)

Edit:
http://www.lua.org/work/doc/manual.html#3.4.6 [import]uid: 13097 topic_id: 17796 reply_id: 67926[/import]

Found a quick workaround:

local count = 0  
for \_, \_ in pairs(t) do count = count + 1 end  
print(count)  

so you could make yourself your own length function!
Hopefully it helps you [import]uid: 13097 topic_id: 17796 reply_id: 67929[/import]

@peach, thanks for the answer

@xxxfanta; thank you very much for the clear explanation… so the official tutorial is a bit dated and should be corrected. http://lua-users.org/wiki/TablesTutorial

This usage is very error prone… but anyway, I could live with it :slight_smile: [import]uid: 11686 topic_id: 17796 reply_id: 67928[/import]

local t = {}  
t[1] = 10  
t[2] = 20  
t[3] = 30  
t[5] = 50   
  
function table.length(t)  
 if type(t) == "table" then  
 local count = 0  
 for \_, \_ in pairs(t) do count = count + 1 end  
 return count  
 end  
end  
  
print("Using #: "..#t .. "\nUsing the new table.length: " .. table.length(t))  

Just add the new table.length-function somewhere at the top and you shouldn’t have any problems :slight_smile:
Maybe somebody can make it even better… Maybe it’s possible to change the standart __len behaviour… Dunno. [import]uid: 13097 topic_id: 17796 reply_id: 67934[/import]

yeah, this works for sure… but a native, faster solution would be better. :slight_smile: haha maybe in next version of lua :slight_smile: [import]uid: 11686 topic_id: 17796 reply_id: 67937[/import]

Wow, xxxfanta, this is great (both the explanation posted in #2 and the work-around code in #6). I’ve seen some puzzling effect that I could not quite understand (which led me to avoid dealing with situation that would require me to figure it out). This really helps.

Thank you!

Naomi [import]uid: 67217 topic_id: 17796 reply_id: 67981[/import]

is not a count of table elements it’s last index in table

xxxfanta is right make your own function to count)
i use
table.count = function(t)
local c = 0
for _ in pairs(t) do
c = c + 1
end
return c
end
[import]uid: 65903 topic_id: 17796 reply_id: 67998[/import]