Home 0 SoundRaider 0 Director 0 Faust 0 Nectarine 9 0 Personal 0
 
 XObjects
 Shockwave Gallery
 Technical Guide for Director Developers
 Director Tips and Tricks
 
 Director Users Group
 DUG Members List

© Andy Wilson, 1998

Sorting Lists of Property Lists in Lingo

Someone this week asked me how to perform a task that crops up quite often if you use lists to store complex data: sorting lists of property lists by one of the properties. For example, you might have a list of property lists, each one of which represents a sort of database record for an individual, storing their name, PRE and other details. In theory you could use such a structure to hold large amounts of data about hundreds of individuals. For the sake of argument we can call each of the inner property lists a ‘record’, and the linear list that holds all the records the ‘database’. In this case one of the records might look like:

[#fName: "Andy", #sName: "Wilson", #email: "andyw@dircon.co.uk"].

And a sample database might look like this:

[
[#fname:"Andy",   #sName:"Wilson", ¬
  #email: "andyw@dircon.co.uk"],
[#fName:"Alec",   #sName:"East", ¬
  #email: "alec@mistral.co.uk"],
[#fName:"Peter",  #sName:"Small", ¬
  #email: "peter@genps.demon.co.uk"],
[#fname:"Bassem", #sName:"Abdallah", ¬
  #email: "AmProd@dial.pipex.com"]
]

The problem starts when you decide that you need to sort the database according to one of the properties you use to describe each individual. Let’s say that you need to sort the whole database so the records are in order according to the surname. There is really quite a neat way to do this. Let’s start by defining the handler, sortPList, that is going to do the work for us. We have to pass it two arguments, propList – our original database, or list of property lists – and propToSortBy, the property we want to sort by. The handler declaration, then, looks like this:

on sortPList propList, propToSortBy

The basic method consists using the original list to create a new property list, tempList, where each property is equal to the value of the property we are looking for in the original list, and it’s value equals that record’s position in the original list. Sound complicated ? All it means is that if we use the following code:

set cnt = count (propList)
set tempList = [:]
repeat with x = 1 to cnt
  set subList = getAt (propList, x)
  addProp (tempList, getProp (subList , propToSOrtBy), x)
end repeat

to produce a list which, if we decided to sort by surname, would look like this:

["Wilson": 1, "East": 2, "Small": 3, "Abdallah": 4]

Each property in this list is the surname, in order, of each individual in the original list, and the value given to that property if the individuals position in the original list – and hence at the moment they have the values 1 to 4. The purpose of this is to take advantage of director’s own list sorting capabilities, since Director can sort a property list according to the names of each property. So, if we ask director to sort this list by entering:

sort (tempList)

this list it now produces will look like:

["Abdallah": 4, "East": 2, "Small": 3, "Wilson": 1]

In this list, each property is one of the original surnames but, crucially, each value points to the person’s position in the original list. By this point we have done 90% of the work needed to produce the sort – or rather we have got director to do the work for us. All we need to do to finish up is to rebuild the original list in the order indicated by the sorted list. To do this, we start with a new, empty result list:

set resultList = []

and then take each record from the old list in the order director has indicated to us when it sorted the temporary list. We can ignore the property names in the list director created for us, all we are interested in is the number values in the list, ie., the numbers 4, 2, 3 and 1 in order. We achieve this by using the code:

repeat with recordNum in tempList
  add (resultList, getAt (propList, recordNum))
end repeat

In this case, the variable recordNum takes the values 4, 2, 3 and 1 in order, and each time around the loop it adds the appropriate record from our original list (record 4, record 2…) onto the end of the new list, resultList. So, Director will take record 4 from the original list, adding it to the result list, then record 2, and so on. The final result is exactly what we were looking for - the original list sorted according to surnames;

[
[#fname:"Bassem", #sName:"Abdallah", ¬
  #email: "AmProd@dial.pipex.com"],
[#fname:"Alec",   #sName:"East", ¬
  #email: "alec@mistral.co.uk"],
[#fname:"Peter",  #sName:"Small", ¬
  #email: "peter@genps.demon.co.uk"],
[#fname:"Andy",   #sName:"Wilson", ¬
  #email: "andyw@dircon.co.uk"]
]

That means that if we have a database listing, we can sort it by any property we choose, using:

set myList = sortPList (myList, #fName)
or
set myList = sortPList (myList, #sName)
or
set myList = sortPList (myList, #email)

To sum up, the entire code listing for our sorting function looks as follows:

on sortPList propList, propToSortBy
  set cnt = count (propList)
  set tempList = [:]
  repeat with x = 1 to cnt
    set subList = getAt (propList, x)
    addProp (tempList, getProp (subList, ¬
	  propToSOrtBy), x)
  end repeat
  sort tempList
  set resultList = []
  repeat with recordNum in tempList
    add (resultList, getAt (propList, recordNum))
  end repeat
  return resultList
end

This technique is useful in many situations other than lingo databases – recently I was trying to build a three-d environment where each object was described by property lists just like these, and then I had to draw each object in order according to either the x, y, or z values of the object, depending on the view. All I had to do to change the perspective was take my list of objects, stretch each object in proportion to their distance from the observer’s position, order them according to whichever was the appropriate dimension for the current perspective view, then draw them on stage in that order, starting with the furthermost object in sprite channel 1, then the next object in channel 2, and so on. That way, each object was drawn with the correct perspective. Hopefully you’ll find yet more applications for using this technique.

As usual, if you have any ideas for future articles, let me know by mailing me on andyw@dircon.co.uk.

 
There are currently users connected. You have viewed 1 pages. Unless otherwise stated, all content is ©1996-2003 Andy Wilson. If you have any questions or suggestions you can mail me: andyw at dircon dot co dot uk. This site is hosted by LShift Ltd.