Topic 03-tables.md
Tables
It is commonly said that a Lua table has both an array and a map part. It is more correct to say that it can be used both ways.
Here is a more general table – note that the length operator #
does not see any
non-array keys:
t = {10,20,30,40,50; sorted=true} print(t[1], #t, t[#t]) --> 10 5 50 print(t["sorted"], t.sorted) --> true true
In Lua, t.sorted
is defined to be t['sorted']
. (This is one of several simularities Lua
has with JavaScript.)
This gives us a way to do ‘objects’ or ‘structures’ with tables:
-- 'point' objects s1 = {x = 1, y = 2} s2 = {x = 0, y = 4} -- adding two points sum = { x = s1.x + s2.x, y = s1.y + s2.y } print(sum.x, sum.y) --> 1 6
Something like t.function
is a syntax error, because function
is a keyword. In this case
you must say t["function"]
. The general way to construct tables is
t = { ["function"] = 1, ["end"] = 2 }
In Lua, tables are used to represent arrays. But inserting a nil
value creates a hole,
and the length operator #
is no longer defined.
You must be careful not to insert any holes by
accident. Consider a task in which you want to get a list of objects from a list of
names using a function getObject
which may return nil
. You furthermore want
the resulting list to have the same length as the list of strings:
local null = {} local objects = {} for i = 1,#strings do local obj = getObject(strings[i]) if obj then objects[i] = obj else objects[i] = null end end
That is, put some distinct and unique value into the array that stands for nil
. Then
when using the list of objects, test for this unique value:
for i = 1,#objects do local obj = objects[i] if obj == null then print(i,'nada') else print(i,tostring(obj)) end end
The list of objects remains a perfectly good array.
(In this code, variables are explicitly declared as being local; we'll see why this is such a good idea later.)
Most of the table functions are meant to operate on arrays; you can sort them with table.sort . In the simple case the table must only contain numbers (or sortable objects), but a sort function can be provided.
Arrays of strings can be joined together with table.concat . This is the most efficient way to build up large strings:
local res = {} for i = 1,1000 do res[i] = "hello "..i end str = table.concat(res)
(Note that table.concat is picky about the array elements; they must either be numbers or strings. If in doubt, use tostring to convert values first.)
The most commonly used function with tables is pairs which allows you to iterate over all the elements. There is a corresponding function ipairs which works for arrays:
for i,v in ipairs{10,20,30; x=1} do print(i,v) end --> 1 10 --> 2 20 --> 3 30
Unlike pairs , ipairs will give you the keys in the correct order, and it will only access the array elements.