8.4 Tables

A table is a collection of many different data items which can be of any type. A table is the universal data structure in Hollywood. It can be used in many different forms, e.g. as an array, as a list or as a record. Tables are created by using the constructor {...}. For example, the following code creates an empty table:

a = {}

An empty table is of no use because there is no data in it and Hollywood requires that all fields of a table must be initialized before they are used. Thus, if you would try to access a field of this empty table now by stating for instance

b = a[0]

you would get an error stating that this field 0 has not been initialized yet. You may only access fields of the table, that you have initialized before. The correct version would therefore be:

a[0] = 5     ; assign 5 to a[0]
b = a[0]     ; assign 5 to b

Or you could also use the constructor to initialize the table:

a = {5}      ; create a table with 5 as the element 0
b = a[0]     ; assign 5 to b

You can also use the constructor to initialize the table with multiple items. The constructor assigns the specified values to the table starting at index 0. For example:

a = {1, 2, 4, 8, 16, 32, 64, 128, 256} ; create table with 9 elements
b = a[7]     ; assign 128 to b (128 is at index 7 in a)

Additionally, you can use the Dim and DimStr statements to create and initialize a table of a specified size.

One thing that is important to know when dealing with tables is that when you assign a table to a new variable, the new variable receives only a reference to the table. It does not receive an independent copy of the table. Consider the following code:

a = {1, 2, 3, 4, 5}       ; create a table with 5 elements
b = a                     ; create a REFERENCE of a in b
b[0] = 2                  ; change element 0 to 2
DebugPrint(a[0], b[0])    ; will print "2 2"

If you want to create an independent copy of a table, you can use the CopyTable() function for this.

In Hollywood, indices cannot only be positive integers, but also negative integers, floating point values and even strings. For example, you can also initialize negative elements of the table:

a       = {}  ; create empty table
a[-5]   = 3   ; assign 3 to index -5
a[1.5]  = 2   ; assign 2 to index 1.5

If you want to do this custom initialization in the constructor, you will have to use square brackets. The three lines above could also be written as:

a = {[-5] = 3, [1.5] = 2}   ; initialize new table

If you want to use strings as indices, you can use the following statements:

a         = {}          ; create empty table
a["name"] = "John Doe"  ; assign "John Doe" to index "name"
a["age"]  = 20          ; assign "20" to index "age"
a["sex"]  = "male"      ; assign "male" to index "sex"

An easier way to use strings as indices is to use the '.' expression. The following code does the same as the code above:

a         = {}          ; create empty table
a.name    = "John Doe"  ; assign "John Doe" to index "name"
a.age     = 20          ; assign "20" to index "age"
a.sex     = "male"      ; assign "male" to index "sex"

Last but not least, you can also use the constructor to initialize a table with named indices. The following code does the same as the two snippets above:

a = {["name"] = "John Doe", ["age"] = 20, ["sex"] = "male"}

Or the easier way:

a = {name = "John Doe", age = 20, sex = "male"}

You can access named elements of a table also in two ways:

b = a["name"]
b = a.name

Both lines will assign the same value to b. The most common way to access and initialize named elements of a table is to use the dot method. Please note that Hollywood does not distinguish between upper and lower case names, so you could also access the elements above by using a.NAME or even a.nAmE.

There is, however, an exception: When using brackets to initialize or access table fields, Hollywood distinguishes between upper and lower case string indices. Further details on this topic can be found in the documentation of the RawGet() command. See RawGet for details.

You can add elements to a table by simply assigning a value to them. If you want to remove elements, you have to set their value to Nil. That is another big advantage of Hollywood's programming language which is dynamically typed. Tables (arrays) are not limited to a specific size: You can grow and shrink them as you like.

You can also use tables which combine named and numbered elements, for instance:

a = {x = 1, y = 2, 10, 11, 12, 13, z = 3, [6] = 16, 14, 15, obj="Cube"}

This creates a new table and initializes elements 0 to 6 with the numbers 10 to 16. Additionally, it creates four elements named x, y, z and obj and initializes them to 1, 2, 3, and "Cube".

We are now going to have a look at some more complicated table constructions. You might want to skip the following section if you are just starting out with Hollywood.

It is also possible to use tables within tables. Have a look at the following example:

buts = { {x1 = 0, y1 = 0, x2 = 100, y2 = 50},
    {x1 = 100, y1 = 0, x2 = 80, y2 = 50},
    {x1 = 180, y1 = 0, x2 = 100, y2 = 50} }

This code creates a new table called buts and initializes the first three elements with tables which contain the start and end position of each button. We could now use the following code to create those three buttons:

For k = 0 To 2
    CreateButton(k + 1, buts[k].x1, buts[k].y1, buts[k].x2, buts[k].y2)

Multi-dimensional tables are also no problem. The following code creates a matrix of size 50x100 and initializes it to zero:

N = 50
M = 100
mtx = {}                            ; create an empty table
For i = 0 To N - 1
    mtx[i] = {}                     ; create a new row
    For j = 0 To M - 1
            mtx[i][j] = 0           ; initialize element

You can also use the Dim and DimStr statements to create multi-dimensional tables.

You do not have to use constants when initializing a table using a constructor. You can use variables whereever you want. For example:

s$ = "test"
i = 5
a = {[s$] = "An element", [i * 5 + 1] = "Another element"}

This code will create the element a.test (which is the same as a["test"]) and assign the string "An element" to it. In addition, it creates the element a[26] and assigns the string "Another element" to it.

Do not get confused when you see something like this:

x = 5
y = 4
a = {x = x, y = y}     ; assign 5 to "x" and 4 to "y"

The table declaration above is no nonsense. It creates a table with two elements named x and y. The element x gets the value of the variable x which is 5 and the element y gets the value of the variable y which is 4. An other way to write the code above would be for instance:

x = 5
y = 4
a = {}        ; empty table
a.x = x       ; assign 5 to a.x
a.y = y       ; assign 4 to a.y

Both snippets do the very same.

Finally, you can place functions in your tables. Here is an example:

a = {Add = Function(v1, v2) Return(v1 + v2) EndFunction,
     ShowBrush = DisplayBrush}
a.ShowBrush(1, #CENTER, #CENTER)  ; calls DisplayBrush()
b = a.Add(15, 16)                 ; returns 31 to b

The code above creates a table with two functions. The first function is a custom function which adds two values and the second function simply refers to the Hollywood function DisplayBrush(). You could also write this code in the following way:

a = {["Add"] = Function(v1, v2) Return(v1 + v2) EndFunction,
     ["ShowBrush"] = DisplayBrush}
a["ShowBrush"](1, #CENTER, #CENTER)  ; calls DisplayBrush()
b = a["Add"](15, 16)                 ; returns 31 to b

Show TOC