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.

Next: Coroutines

generated by LDoc 1.3