PDA

View Full Version : Another question for Tink - Overloading and Collections


CDHBookingEdge
11-09-2006, 09:04 AM
When I was doing .NET type stuff I used keyed lists a lot. Essentially what I had set up were data classes of a sort that were able to be accessed this way:
object = List["Tink];

And that would return the object that had you as it's Key.

I guess my question is, is there anyway of doing this with AS3? I mean I could have a method that allows access such as this:
object = List.GetObject("Tink");

But it's not quite as elegant and easily readible as the other notation. If there is no other way then so be it.

I was just wondering if you knew of any ways around that "shortcoming".

Thanks in advance,
Christopher

Tink
11-09-2006, 09:21 AM
If you had a dynamic class you could use that approach, for instance Object is dynamic

var list:Object = new Object();
list[ "Tink" ] = 30;
list[ "Christopher" ] = 40;

trace( list[ "Tink" ] );
trace( list[ "Christopher" ] );Wot you miss with this approach is any type checking. If you used the getObject() approach you could check the type of the object being returned, and again for the object being set. with the above approach you might want to store numbers only, but there no stopping anyone making a mistage and storing any other type in there.

CDHBookingEdge
11-09-2006, 09:36 AM
ok..but...hmmm..lemme look at that...

So I could do something like this then? (kinda pseudocoding it here forgive me)

class User
{
var name:String;
var email:String;
var numPost:int;
var joinDate:Date;
var location:String;
}

var list:Object = new Object();

var thisUser = new User();
thisUser.name = "Tink"
(etc..for defining the thisUser variable)
list["Tink"] = thisUser;

thisUser.name = "Christopher"
(etc..for defining the thisUser variable)
list["Christopher] = thisUser;

trace( list[ "Tink" ] );
trace( list[ "Christopher" ] );


Am I right in taking it that far? If so then heck there's a keyed collection right there isn't it? Now I guess my next question is can I go thru it serially? by that I mean can I go thru list as:

trace( list[ 0] ); // brings up Tink
trace( list[ 1 ] ); // brings up Christoper


I think I was right in my earlier hypothesis, you do rule! :D

Christopher

Tink
11-10-2006, 04:39 PM
Sorry for the slow reply.

No you would be able to go through the properties serially. You could access them like

trace( list.Tink );
trace( list.Christopher );

as basically it's just created untyped vars within the object. Personally I'd say its not a very good approach. You'd be much better off with methods to add, remove and access items and make sure the type is User.

MichaelxxOA
11-10-2006, 04:54 PM
It wouldn't be a bad idea to implement some sort of 'Generics'-esk implementation of a collection. Which shouldn't be an issue given the new 'is' operator.

MichaelxxOA
11-10-2006, 05:09 PM
You could possibly do something like this...

I didn't test it (:(), but I don't see any issues. It may need tweaking though.


package
{
/**
* A very simple example of a collection
* with java generics type functionality.
*
* API is very generic.
*
* Constructor -
* Pass in class name, if undefined it will
* default to Object.
*
* Methods
*
* uint size()
* Returns how many items are in this collection.
*
* void add( obj, index )
* Adds the object at the index specified. If left null
* object gets pushed onto collection.
* The obj type has to be of the type you specify in the
* constructor.
*
* * get( index )
* Returns the object at the specified index. There is no
* return type specified so you can place what returns into
* any variable.
*
* * remove( index )
* Removes and returns the object at the specified index.
*/
public class GenericCollection
{
protected var className:Class = Object;

protected var list:Array;

/**
* Constructor
*
* @param The type of objects this collection is to hold.
*/
public function GenericCollection( type:Class )
{
className = type;
list = new Array();
}

/**
* Returns how many items are in the collection.
*/
public function size():uint
{
return list.length;
}

/**
* Adds the object at the specified index. The object must
* be of the same type as you specified in the constructor.
* If you don't define an index then it is just pushed onto
* the collection
*
* Returns whether or not the obj was successfully added.
*/
public function add( obj:*, index:uint=null ):Boolean
{
if ( !(obj is className) ) return false; // TODO: Throw an error

( index == null ) ? list.push( obj ) : list[ index ] = obj;
return true;
}

/**
* Removes and returns the object at the specified index.
*
* @param The index of the object to remove and return.
*/
public function remove( index:uint ):*
{
var temp:* = list[ index ];
list.splice( index, 1 );

return temp;
}

/**
* Returns the object at the specified index.
*
* @param The index of the object to return.
*
*/
public function get( index:uint ):*
{
return list[ index ];
}
}
}


That'd be the simplest form of my idea I imagine.

Michael

CDHBookingEdge
11-10-2006, 05:21 PM
Thanks Michael, I'll take a look at it and play around with it. My Dream..I guess is to have some type of collection that I can/could reference the items in it by either this way:
item = myKeyedList["Michael"];
or this way:
item = myKeyedList[3];
but not sure how well that could be done with AS, being that there's really no op overriding. If there is a way then it could be kinda cool to even be able to link them up and have something where you could go:
item = myKeyedList["Michael"].Addresses["Home];
or even
areacode = myKeyedList["Michael"].PhoneNums["Mobile"].areacode;
If you're familiar with C# and .NET there's an interesting implementation on Code Project by Marc Clifton that has a KeyedList implementation that I'm kinda trying to mirror. If you look for Generic Keyed List over there you'll see it.

Anyway thanks and I'll for sure give it a shot,
Christopher

dr_zeus
11-10-2006, 06:46 PM
The flash.utils.Proxy (http://livedocs.macromedia.com/flex/2/langref/flash/utils/Proxy.html) class could probably give you the functionality you want. Proxy will let you listen for any property requests that an object receives (even properties that don't technically exist). So you can retrieve values with

myObject["Blah"]

or

myObject[0]

When you save a value in your collection, you could save it an an Array so that you have indexes, AND you can also place it in an object so that you can request the value with a property string. Based on the property type requested (numeric for index or string for a property name), you can return the correct value.

CDHBookingEdge
11-10-2006, 07:00 PM
Hmm sounds like I might needs ta check that class out ;-) Having one of those "brain overload" moments I think. Maybe based on the fact that I'm hitting on 12 hours up. But it does sound cool. And what you said as far as:
When you save a value in your collection, you could save it an an Array so that you have indexes, AND you can also place it in an object so that you can request the value with a property string.

Sounds kind of like how Marc Clifton did his keyed list on code project. He used IDictionary<TKey, TValue> and IList<TKey>. Hmm come to think of it the flash.utils has a Dictionary class doesn't it? Darn, the mx.* source is provided but not the flash.* source with the Flex SDK huh? That bites. Understandable, but darn! So kinda sounding like there are a lot of ways to possibly go about it...hmmm I like when that happens. ;-)

Thanks everyone,
Christopher