Create and work with Lua like tables in Swift

The main difference between Lua and Swift despite the fact that both are easy to work with once the allocs and inits are removed, is that Swift is too rigid. Where Lua is flexible, Swift is rigid, but this is due to design. Swift is supposed to be a typesafe langauge. Which simply means that if you have a variable declared as string, you cannot store a number to it. The beauty of Lua in this aspect is that you can store whatever you want in a variable, including functions, and data blocks.

Lua Tables

If you have worked with Lua, you will realise that tables are the most flexible and easy to use feature in Lua that makes developing with Lua so much more interesting and easy. The tables are a combination of both Arrays and Key-Value pairs. In some cases it is also a hashtable (if you want to add objects). Here's an example

local myTable = {}
myTable[1] ="One"
myTable["One"] = "Une"
myTable[10] = "Ten"

This now creates a Lua table with the three elements, BUT... there are 10 elements in the table array and 1 element in the keyvalue pair. However there are 3 non-nil elements. Like in the case of adding an element at index 10, Lua resizes the array and fills the in-between items with a nil value and adds the 10th element with a value. If you were to access any other item, it would return a nil. If you were to query the number of items in the table using the table.maxn function, you would get 10 as the return value. If you were to query using the # sign, you would get 1 as there is only 1 contiguous value.

Tables in Swift

Remember the keyword Typesafe? So most Swift tables are of a particular type. If you look at some of the code written in Swift that use generics to allow for a variety of types (it is painful writing the same code over and over for every variable type, plus when you get to custom classes, you do not know what that would be). Generics make it easier to work with because it is used like a template, like in the code

func sampleFunction<t>(theParameter:T){
  println("We have the parameter \(theParameter)")
}

var number:Int = 10
var name: String = "Name"

sampleFunction(number)
sampleFunction(name)

This will not accept any type of parameter you pass it and it will work. Otherwise you would have to create two functions one for Int and one for String to make this work.

So when you work with arrays and dictionaries (Key-Value pairs) you have to use a type, for example

var myArray:[String]
or
var myArray[Int]

and with the KeyValue pairs it gets even more interesting because the key has to be a String and the value could be anything. The goood thing about Swift is that you can have multiple types in the same array if you use the AnyObject type.

My Custom Class - solution

Here's what my little swift class type works like

//Create a new table
var _table = luaTable()

//Add an element as a key-value pair
_table["One"] = "Eins"

//Add some index elements
_table[1] = "Five"
_table[0] = "One"
_table[7] = "ThirtyFive"

//Note: The element list is now 7 with 0 and 1 having data then nils till 6 and finally 7 with data

println("# \(~!_table) ")
// Since # is not an operator that can be overloaded, I had to use ~! 
// this returns the number of elements from index 0 that are contiguous.


_table.remove(1)
_table.insert(3, "Three")

print("\(_table["One"])")
print("\(_table["Three"])")

// This also has the facility to save the data onto the device
_table.save()


// Add some more key-value pairs
_table.addData(["Hello":"Swift", "Right":"Left"])


// Add some data from a string that contains assignments
_table.addDataFromString("a=b,c=d,e=f,g=h")


// This will load the data back from the device, discarding the current data
_table.load()

//Note: You can save the data with a different filename to save multiple copies.

// Add a series of items from an array
_table.addArray([1, "Hello", 2, nil, 4.5, 7, 3.14, "Pie"])


This is still experimental and has a couple of shortcomings, In Lua you can nest tables, where the table element can be another table. This does not accept nested tables as yet. It could work, but it is unstable.

It can store objects and retrieve them too, like
_table[myClassInst] = "MyClass"
//where myClassInst is a class instance (Object) of myClass

println("\(_table[myClassInst])")

It does not save functions as yet, when it does this would become quite useful.

If you are interested in learning swift or following my swift related stuff, please head over to swift.oz-apps.com where there are more articles and focused specifically at swift.

Comments

Popular Posts