Early programming languages had a notion of
array,
essentially an ordered list of variables. It should be clear
that there is no natural way of ordering the keys of a Lua
table. However, if we call a table, whose keys form a consecutive
sequence of positive integers starting with 1, a
list
then we think of a table
t as made up of two parts:
a list part,
t[1],
t[2], ... ,
t[n],
and a non-list part with
t[n+1] either undefined or
nil. The code
for key, value in ipairs (t) do .... end
will iterate over the list part of
t in order, whereas
for key, value in pairs (t) do .... end
will iterate over all the keys of
t, but in no predictable
order.
The expression
#t should evaluate to the length of the
list part of
t when the list part has been created in
order. However, if holes are punched in the table things get dodgy:
t = {}
for i = 1,7 do t[i] = i end
print (#t) --> 7
t[3] = nil -- list part now has only two items
print (#t) --> 7
t[8] = 8
print (#t) --> 8
A table can be used as a stack if it is created using code like this:
stack = function ( )
local push, pop = table.insert, table.remove
return { push = push, pop = pop }
end
x = stack ( )
x:push "tom"
x:push "dick"
x:push "harry"
print (#x) --> 3
print (x:pop ( )) --> harry
print (#x) --> 2
There is a reason why the size operator # does not in all cases
return the number of items in the list part of a table. Imagine
a table with millions of entries. There is no way of checking the
size of the list part except by testing the keys 1,2, ... in
order until a nil value is encountered. This method takes a time
linear in the size of the list part. The actual implementation of
# is a compromise. Treat the table table respectfully, without
knocking holes in it, and you get a fast correct size operator.