Reputation: 896
Given a table with mixed indexes like:
table = {
foo = 'bar'
[1] = 'foobar'
}
My question is about the #
which gives the last index which is not separate through a gap while iterating through the table.
print(#table)
will give the output 1.
table = {
foo = 'bar',
lol = 'rofl',
[1] = 'some',
[2] = 'thing',
[3] = 'anything',
[4] = 'else'
}
print(#table)
should print 4
Can I be 100% sure that the #
will never be distracted by non-numeral indexes?
Are those indexes really unregarded at every time?
Upvotes: 1
Views: 164
Reputation: 81052
Yes, you can count on that (in lua 5.1).
From the lua reference manual:
The length operator is denoted by the unary operator #. The length of a string is its number of bytes (that is, the usual meaning of string length when each character is one byte).
The length of a table t is defined to be any integer index n such that t[n] is not nil and t[n+1] is nil; moreover, if t[1] is nil, n can be zero. For a regular array, with non-nil values from 1 to a given n, its length is exactly that n, the index of its last value. If the array has "holes" (that is, nil values between other non-nil values), then #t can be any of the indices that directly precedes a nil value (that is, it may consider any such nil value as the end of the array).
lua 5.2 allows for the __len
metamethod to operate on tables and that means #
can do other things. See @kikito's answer for some examples.
Upvotes: 3
Reputation: 52708
Etan answer is correct, but not complete.
In Lua, if a table's metatable has a __len
function, it will control what the #
operator spits out. One can define it so that it takes into account the non-array keys.
local mt = {__len = function(tbl)
local len = 0
for _ in pairs(tbl) do len = len + 1 end
return len
end}
This demonstrates the thing:
local t = {1,2,3,4,foo='bar',baz='qux'}
print(#t) -- 4
setmetatable(t, mt)
print(#t) -- 6
If you really want to make sure that you get the "proper" array-like length, you must use rawlen
instead:
print(rawlen(t)) -- 4, even with the metatable set
Edit: Note that __len
does not work as I mention on Lua 5.1
Upvotes: 2
Reputation: 1913
The only way is to iterate through entries and count them. Iterate with ipair through the item and increment counter then return result.
function tablelength(T)
local count = 0 for _ in pairs(T) do
count = count + 1 end
return count
end
The # operator only work for hash table type.
See: How to get number of entries in a Lua table?
Upvotes: 0