AS3: Collection & Iterator
View Collection Documentation
View Iterator Documentation
Download Class & Example Files
Anyone who has worked with me in the past probably knows my distaste for Cairngorm and how I think it overcomplicates things. One really nice feature of it, however, is value objects (now known as data transfer objects, I believe) and collections. Value objects allow you to store data in a strongly typed class for later retrieval and a collection is just basically a fancier word for a strongly typed array that holds those value objects.
I use VOs to this day on pretty much any AS2 project that I pull external data into to store those objects much like I used to when I was a beginner and stored dynamic properties on an Object. This is a much more elegant way of controlling those objects and with a collection I can do things like get an object out by an ID or set up an extension of the Collection class and get objects out by whatever I want.
The Iterator class is just a port of the AS2 Iterator by Adobe as I couldn't find an AS3 version anywhere. Here that is:
-
/**
-
* @author Adobe [http://www.adobe.com]
-
* @author Ported to AS3 by Matt Przybylski [http://www.reintroducing.com]
-
* @version 1.0
-
*/
-
-
package com.reintroducing.utils
-
{
-
public class Iterator
-
{
-
//- PRIVATE & PROTECTED VARIABLES -------------------------------------------------------------------------
-
-
private var _collection:Collection;
-
private var _cursor:int;
-
-
//- PUBLIC & INTERNAL VARIABLES ---------------------------------------------------------------------------
-
-
-
-
//- CONSTRUCTOR -------------------------------------------------------------------------------------------
-
-
/**
-
* Initialize the Iterator and maintain a link to it's Collection.
-
*
-
* @param $coll Collection to which this Iterator belongs.
-
*/
-
public function Iterator($coll:Collection):void
-
{
-
this._collection = $coll;
-
this._cursor = 0;
-
}
-
-
//- PRIVATE & PROTECTED METHODS ---------------------------------------------------------------------------
-
-
-
-
//- PUBLIC & INTERNAL METHODS -----------------------------------------------------------------------------
-
-
/**
-
* Returns true if the iteration has more items.
-
*
-
* @return Boolean true if iteration has more items.
-
*/
-
public function hasNext():Boolean
-
{
-
return (this._cursor <this._collection.getLength());
-
}
-
-
/**
-
* Return the next item in the iteration and increment the cursor. Returns null if the
-
* iteration has no more items.
-
*
-
* @return Object the next item in the Iteration.
-
*/
-
public function next():Object
-
{
-
return (this._collection.getItemAt(this._cursor++));
-
}
-
-
//- EVENT HANDLERS ----------------------------------------------------------------------------------------
-
-
-
-
//- GETTERS & SETTERS -------------------------------------------------------------------------------------
-
-
-
-
//- HELPERS -----------------------------------------------------------------------------------------------
-
-
public function toString():String
-
{
-
return "com.reintroducing.utils.Iterator";
-
}
-
-
//- END CLASS ---------------------------------------------------------------------------------------------
-
}
-
}
The Collection is also a port of the AS2 CollectionImpl.as class, although, like the Iterator, I took out the interface that goes with it and just made it one class.
-
/**
-
* @author Adobe [http://www.adobe.com]
-
* @author Ported to AS3 by Matt Przybylski [http://www.reintroducing.com]
-
* @version 1.0
-
*/
-
-
package com.reintroducing.utils
-
{
-
public class Collection extends Object
-
{
-
//- PRIVATE & PROTECTED VARIABLES -------------------------------------------------------------------------
-
-
private var _items:Array;
-
-
//- PUBLIC & INTERNAL VARIABLES ---------------------------------------------------------------------------
-
-
-
-
//- CONSTRUCTOR -------------------------------------------------------------------------------------------
-
-
/**
-
* Helper class used to manage a collection of objects. This class is similar to the Java
-
* Collection interface. Developers can extend this class to create new Collection types
-
* that provide additional functionality such as ordering and sorting.
-
*
-
* @return Nothing
-
*/
-
public function Collection():void
-
{
-
super();
-
-
this._items = new Array();
-
}
-
-
//- PRIVATE & PROTECTED METHODS ---------------------------------------------------------------------------
-
-
// Finds an item within the Collection and returns it's index.
-
private function internalGetItem($item:Object):int
-
{
-
var result:int = -1;
-
-
for (var i:int = 0; i <this._items.length; i++)
-
{
-
if (this._items[i] == $item)
-
{
-
result = i;
-
break;
-
}
-
}
-
-
return result;
-
}
-
-
//- PUBLIC & INTERNAL METHODS -----------------------------------------------------------------------------
-
-
/**
-
* Adds a new item to the end of the Collection.
-
*
-
* @param $item * to be added to the Collection. If item is Null it will not be added to the Collection.
-
*
-
* @return Boolean true if the Collection was changed as a result of the operation.
-
*/
-
public function addItem($item:*):Boolean
-
{
-
var result:Boolean = false;
-
-
if ($item != null)
-
{
-
this._items.push($item);
-
-
result = true;
-
}
-
-
return result;
-
}
-
-
/**
-
* Removes a single item from the Collection. Returns false if item is not found.
-
*
-
* @param $item reference to Collection item to be removed from Collection.
-
*
-
* @return Boolean true if item is found and successfully removed. False if item is not found.
-
*/
-
public function removeItem($item:*):Boolean
-
{
-
var result:Boolean = false;
-
var itemIndex:int = this.internalGetItem($item);
-
-
if (itemIndex> -1)
-
{
-
this._items.splice(itemIndex, 1);
-
-
result = true;
-
}
-
-
return result;
-
}
-
-
/**
-
* Removes all items from the Collection.
-
*
-
* @return Nothing
-
*/
-
public function clear():void
-
{
-
this._items = new Array();
-
}
-
-
/**
-
* Returns true if this Collection contains the specified item.
-
*
-
* @param $item * whose presence in this collection is to be tested.
-
*
-
* @return Boolean true if this collection contains the specified item.
-
*/
-
public function contains($item:*):Boolean
-
{
-
return (this.internalGetItem($item)> -1);
-
}
-
-
/**
-
* Returns an item within the Collection using it's index.
-
*
-
* @param $index location of item within the Collection.
-
*
-
* @return * reference to item.
-
*/
-
public function getItemAt($index:int):*
-
{
-
return this._items[$index];
-
}
-
-
/**
-
* Returns an iterator over the elements in this collection. There are no guarantees concerning
-
* the order in which the elements are returned (unless this collection is an instance of some
-
* class that provides a guarantee).
-
*
-
* @return Iterator object that is used to iterate through the collection.
-
*/
-
public function getIterator():Iterator
-
{
-
return (new Iterator(this));
-
}
-
-
/**
-
* Returns the current length
-
*
-
* @return int value reflecting the number of items in this Collection.
-
*/
-
public function getLength():int
-
{
-
return this._items.length;
-
}
-
-
/**
-
* Returns true if the Collection is empty.
-
*
-
* @return Boolean true if Collection is empty.
-
*/
-
public function isEmpty():Boolean
-
{
-
return (this._items.length == 0);
-
}
-
-
//- EVENT HANDLERS ----------------------------------------------------------------------------------------
-
-
-
-
//- GETTERS & SETTERS -------------------------------------------------------------------------------------
-
-
-
-
//- HELPERS -----------------------------------------------------------------------------------------------
-
-
public function toString():String
-
{
-
return "com.reintroducing.utils.Collection";
-
}
-
-
//- END CLASS ---------------------------------------------------------------------------------------------
-
}
-
}
Now, I can't claim to have done a ton of stress tests on these classes, but it works for the basic usage that I've used it for so far. Here is an example of a VO and Collection I set up for a fake project (which you can preview in the example files). This is the XML file we used:
-
<?xml version="1.0" encoding="UTF-8"?>
-
-
<info>
-
<entry name="Portfolio" id="0" src="http://www.reintroducing.com" />
-
<entry name="Flash Dev Blog" id="1" src="http://evolve.reintroducing.com" />
-
<entry name="Company" id="2" src="http://www.b-r-e-e-d.com" />
-
<entry name="Girlfriend" id="3" src="http://www.jessicanovales.com" />
-
<entry name="Sport" id="4" src="http://www.nba.com" />
-
</info>
It's just some awesome information about myself all wrapped up into one neat little XML file.
Main.as
-
/**
-
* @author Matt Przybylski [http://www.reintroducing.com]
-
* @version 1.0
-
*/
-
-
package com.reintroducing
-
{
-
import flash.display.Sprite;
-
import flash.events.Event;
-
import flash.net.URLLoader;
-
import flash.net.URLRequest;
-
-
import com.reintroducing.debug.Environment;
-
import com.reintroducing.vo.TestVO;
-
import com.reintroducing.vo.TestVOCollection;
-
-
public class Main extends Sprite
-
{
-
//- PRIVATE & PROTECTED VARIABLES -------------------------------------------------------------------------
-
-
private var _env:Environment;
-
private var _testVOCollection:TestVOCollection;
-
-
//- PUBLIC & INTERNAL VARIABLES ---------------------------------------------------------------------------
-
-
-
-
//- CONSTRUCTOR -------------------------------------------------------------------------------------------
-
-
public function Main():void
-
{
-
this._env = Environment.getInstance();
-
this._env.setPaths("../", "");
-
-
this.loadXML();
-
}
-
-
//- PRIVATE & PROTECTED METHODS ---------------------------------------------------------------------------
-
-
private function loadXML():void
-
{
-
var xmlURL:String = this._env.basePath + "xml/info.xml";
-
var xmlLoader:URLLoader = new URLLoader();
-
-
xmlLoader.addEventListener(Event.COMPLETE, parseXML);
-
xmlLoader.load(new URLRequest(xmlURL));
-
}
-
-
/**
-
*
-
*/
-
private function parseXML($evt:Event):void
-
{
-
var info:XML = new XML($evt.target.data);
-
var numItems:int = info.children().length();
-
var testVO:TestVO;
-
-
this._testVOCollection = new TestVOCollection();
-
-
for (var i:int = 0; i <numItems; i++)
-
{
-
testVO = new TestVO();
-
testVO.name = info.entry[i].@name;
-
testVO.id = int(info.entry[i].@id);
-
testVO.src = info.entry[i].@src;
-
-
this._testVOCollection.addItem(testVO);
-
}
-
-
this.traceBlogInfo();
-
}
-
-
/**
-
*
-
*/
-
private function traceBlogInfo():void
-
{
-
trace("Entry Name: " + this._testVOCollection.getItemAt(1).name);
-
trace("Entry ID: " + this._testVOCollection.getItemByID(1).id);
-
trace("Entry Source: " + this._testVOCollection.getItemByName("Flash Dev Blog").src);
-
}
-
-
//- PUBLIC & INTERNAL METHODS -----------------------------------------------------------------------------
-
-
-
-
//- EVENT HANDLERS ----------------------------------------------------------------------------------------
-
-
-
-
//- GETTERS & SETTERS -------------------------------------------------------------------------------------
-
-
-
-
//- HELPERS -----------------------------------------------------------------------------------------------
-
-
public override function toString():String
-
{
-
return "com.reintroducing.Main";
-
}
-
-
//- END CLASS ---------------------------------------------------------------------------------------------
-
}
-
}
TestVO.as
-
/**
-
* @author Matt Przybylski [http://www.reintroducing.com]
-
* @version 1.0
-
*/
-
-
package com.reintroducing.vo
-
{
-
public class TestVO
-
{
-
//- PRIVATE & PROTECTED VARIABLES -------------------------------------------------------------------------
-
-
-
-
//- PUBLIC & INTERNAL VARIABLES ---------------------------------------------------------------------------
-
-
public var name:String;
-
public var id:int;
-
public var src:String;
-
-
//- CONSTRUCTOR -------------------------------------------------------------------------------------------
-
-
public function TestVO():void