Tables Tutorial |
|
Lua has a table library to complement its table datatype. Examples on this page use functions from the standard table library. You can find more information about the Lua table library in section 5.5 of the Reference Manual [2]. There is more information in the TableLibraryTutorial.
Tables are created using table constructors, which are defined using curly brackets, e.g. { } . To define an empty table we can do the following.
> t = {} -- construct an empty table and assign it to variable "t"
> print(t)
table: 0035AE18
Tables can be used to hold arrays of information. Table constructors can contain a comma separated list of objects to create an array. The array elements can be accessed using square brackets, table[index]. e.g.:
> t = { 1,1,2,3,5,8,13 }
> print( t[1] )
1
> print( t[0] )
nil
> print( t[4] )
3
t[0] has the value nil, i.e. there is no element at position 0. The t = { 1,1,2,3,5,8,13 } line is equivalent to the following:
> t = {}
> t[1]=1 t[2]=1 t[3]=2 t[4]=3 t[5]=5 t[6]=8 t[7]=13
We can find the size of a table using the standard table library function # operator (i.e. get number of elements)
> = # t 7
table.insert(table,value) function.
> table.insert(t,21)
> = # t
8
> = t[7], t[8]
13 21
table.insert(table,position,value) function. We can also use the table.remove(table,position) to remove elements from a table array.
> table.insert(t,4,99) > = t[3], t[4], t[5] 2 99 3 > table.remove(t,4) > = t[3], t[4], t[5] 2 3 5
ipairs() operator. This will provide the next indexed key, in ascending order, each time it is called.
> for i,v in ipairs(t) do print(i,v) end 1 1 2 1 3 2 4 3 5 5 6 8 7 13 8 21
table.foreachi(table, print) was suggested, and in LUA 5.1 this still works but is deprecated, expected to be removed from future versions of Lua.
Note that we are not restricted to storing one type of data in an array. We can insert numbers, strings, functions, or other tables, e.g.
> t[4] = "three" > t[6] = "eight" > t[2] = { "apple", "pear", "banana" } > for i,v in ipairs(t) do print(i,v) end 1 1 2 table: 0035DFE8 3 2 4 three 5 5 6 eight 7 13 8 21
Tables can also be used to store information which is not indexed numerically, or sequentially, as with arrays. These storage types are sometimes called dictionaries, associative arrays, hashes, or mapping types. We'll use the term dictionary where an element pair has a key and a value. The key is used to set and retrieve a value associated with it. Note that just like arrays we can use the table[key] = value format to insert elements into the table. A key need not be a number, it can be a string, or for that matter, nearly any other Lua object (except for nil or 0/0). Let's construct a table with some key-value pairs in it:
> t = { apple="green", orange="orange", banana="yellow" }
> for k,v in pairs(t) do print(k,v) end
apple green
orange orange
banana yellow
pairs(), rather than ipairs() to output the values. This is because the keys are no longer numbers and ipairs() iterates only over the indices in a table, whereas pairs() iterates over the keys in a table. Note, there is no guarantee as to the order in which keys will be stored in a table when using dictionaries so the order of retrieval of keys using pairs() is not guaranteed. This caveat even applies to the indexed portion of the table, or in a table that is not being used as a dictionary at all and has only indices as keys.
> t.melon = "green" > t["strawberry"] = "red" > for k,v in pairs(t) do print(k,v) end melon green strawberry red apple green orange orange banana yellow
table.foreach() in LUA documentation and code. This is similar to pairs(), with all of the usual caveats, but has been deprecated in Lua 5.1 and is expected to be removed from future versions of the language.
The table.key = value format is shorthand for table["key"] = value when the key is a string, i.e. t.apple is a little more readable than t["apple"]. This syntactic sugar makes Lua more readable. In the above example:
> t = { apple="green", orange="orange", banana="yellow" }
> t = { ["apple"]="green", ["orange"]="orange", ["banana"]="yellow" }
Note, where our key contains a space we have to use the ["key"]=value format:
> t = { ["keys can contain more than one word"] = "as a string can contain any characters" }
> t["another string"] = 99
You are not restricted to using table constructors as just sequentially indexed lists, or as dictionaries, you can mix the two together, e.g.,
> t = { 2,4,6, language="Lua", version="5.1" }
> for k,v in pairs(t) do print(k,v) end 1 2 version 5.1 3 6 language Lua 2 4 > for i,v in ipairs(t) do print(i,v) end 1 2 2 4 3 6
ipairs() has only output the numerically indexed content, in increasing order, and pairs() has output all of the content, in an undefined order. We can switch backwards and forwards between the two construction styles at will:
> t = { 2,4,6, language="Lua", version="5.1", 8,10,12, web="www.lua.org" }
Due to the numbers/strings coercion, be careful when printing keys. For example:
> t = {}; t[1] = "a"; t["1"] = "b"
> for k,v in pairs(t) do print(k,v) end
1 a
1 b
type(k) shows different information in both cases.
Lua stores all elements in tables generically as key-value pairs. Lua does not differentiate between arrays and dictionaries. All Lua tables are actually dictionaries. In an array the keys are just number object keys.
> t = { 3,6,9 } -- is the same as...
> t = { [1]=3, [2]=6, [3]=9 } -- is the same as...
> t = {} t[1]=3 t[2]=6 t[3]=9
Note that keys are references to objects so you must use the same reference to get the same key into the table. You can use nearly any Lua object as a key in a table. We can demonstrate that keys are references to objects by using a table as a key:
> a = { [{1,2,3}]="yadda" } -- construct a table where the element has a table key
> table.foreach(a,print) -- display the table contents: key-value pairs
table: 0035BBC8 yadda
> = a[{1,2,3}] -- display the element value
nil
a[{1,2,3}] we constructed another table, i.e. the table that we used as a key in the table constructor is not the same one as we used to retrieve the value. If we use the same table in both cases then it will work:
> tablekey = {1,2,3} -- create a table with a variable referencing it
> a = { [tablekey]="yadda" } -- construct a table using the table as a key
> table.foreach(a,print) -- display the table elements
table: 0035F2F0 yadda
> = a[tablekey] -- retrieve a value from the table
yadda
> print(tablekey) -- the table value is the same as the key above
table: 0035F2F0
Aside: The fact that keys are references, and strings can be used, tells us something about Lua's internals. We must be referring to the same string when we get and set the value or table string keys wouldn't work! Strings are not duplicated in Lua internally, so when you reference a string with the same value you are referring to the same string.
> t = { apple=5 }
> a = "apple"
> b = "apple"
> print(t.apple, t[a], t[b]) -- all the same value because there is only one "apple"!
5 5 5
Just to demonstrate that we can use nearly all Lua objects here is a function as a key:
> t = { [function(x) print(x) end] = "foo" }
> for key,value in pairs(t) do key(value) end
foo
"foo". We iterate over the table executing the key (i.e. function) and passing it the value of the function, which it print out: "foo".
For more information about the for statement and the pairs function, read the ForTutorial. Note that both table.foreach() and table.foreachi() are deprecated in Lua 5.1, and so, pairs() and ipairs() should be used in conjunction with a for loop to iterate tables (see ForTutorial for more details)