Question about the length operator

Are all indexes of a table starting from 1 until #table always a non-nil value? If not, how does #table work and how to get the actual length of a table starting from 1 until a nil value?

I’m asking this because it says my table length is 1024 yet there’re multiple nil values in that range…

#Table gets the tables length
ex.

Table = {5, 'Random', 0, 4, 'Empty'}
Print(#Table) --Prints 5

That being said it won’t work for dictionaries.

What about a mix table (where the keys are integers but there are a few gaps in between?)

I don’t understand what you mean

Example:
local table = {1, 2, 3, [5] = 5}
Would the length operator work here?

Yes but only for index 1, 2, and 3. This should explain more.

local Table = {1, 2, 'Random', [5] = 5, 'RandomB'}
Print(#Table) --Prints 4

That actually prints 5, not 4. The table you made will look like this:

{
	[1] = 1,
	[2] = 2,
	[3] = "Random",
	[4] = "RandomB",
	[5] = 5
}

Are you sure? I just tried it in studio and it printed 4

You are right I did not know it adds it to the total length if you set a key to the next available one

Yeah, if you initialize a table by mixing array-like values and key-values like this:

local Table = {1, 2, 'Random', [5] = 5, 'RandomB'}

it will ignore all the key-value initializations and do the array-like ones first. So basically you get:

local Table = {1, 2, 'Random', 'RandomB'}
--and then
Table[5] = 5
1 Like

To pretty much clear up everything any value in a table will be considered when u use the length operator, although if u use the length operator on a dictionary that won’t work.
Ex:

local MyDic = [“Random”]

 #MyDic — wont work.

local MyTable = {[1] = 5, “apple’} — works and prints 2.
1 Like

No. See:

local t = {1}
t[3] = "a"
t[4] = "b"
print(#t) -- prints 4. What?

More proof:

local t = table.create(100, 1)
for i = 2, 99 do
  t[i] = nil
end
print(#t) -- prints 100

The details are not documented for Luau (although they are for Lua) (edit: it actually is also undefined in stock Lua). It’s something to do with how tables pre-allocate the array part of their tables.

Basically, if you will have nil elements in your table, don’t rely on the # operator at all. It’s extremely unintuitive how it works with mixed/sparse tables and I don’t think it’s actually documented anywhere.

Edit: more discussion (and complaints) can be found in this thread

Edit2: see also the documentation of the length operator for Lua 5.2, which is a very close cousin to Luau:

3.4.6 – The Length Operator

The length operator is denoted by the unary prefix 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).

A program can modify the behavior of the length operator for any value but strings through the __len metamethod (see §2.4).

Unless a __len metamethod is given, the length of a table t is only defined if the table is a sequence , that is, the set of its positive numeric keys is equal to {1…n} for some non-negative integer n . In that case, n is its length. Note that a table like

{10, 20, nil, 40}

is not a sequence, because it has the key 4 but does not have the key 3 . (So, there is no n such that the set {1…n} is equal to the set of positive numeric keys of that table.) Note, however, that non-numeric keys do not interfere with whether a table is a sequence.

1 Like

#MyDic didn‘t work because it isn‘t a table.