Cursor/Iterator for Vector and Array

Along with Flex came IViewCursor which provides a way to itererate through ICollectionView classes like ArrayCollection and XMLListCollection. Sometimes though we’re dealing with Vector or Array or are developing an ActionScript-only project. Here’s a cursor/iterator that will allow you to navigate a Vector or Array:

package com.aaronhardy
{
import flash.utils.Proxy;
import flash.utils.flash_proxy;

use namespace flash_proxy;

/**
* Allows for maintaining an index and iterating through a vector or array of objects.
*/
public class VectorCursor extends Proxy
{
/**
* The collection the cursor is navigating.
*/
protected var collection:*;

/**
* The current cursor index.
*/
protected var index:int;

public function VectorCursor(collection:*)
{
this.collection = collection;
}

/**
* The item at the current cursor index.
*/
public function get current():Object
{
return index > -1 && index < collection.length ? collection[index] : null;
}

/**
* The current cursor index.
*/
public function get currentIndex():int
{
return index;
}

/**
* Moves the cursor index to the first item.
*/
public function seekFirst():void
{
index = 0;
}

/**
* Moves the cursor index to before the first item.
*/
public function seekBeforeFirst():void
{
index = -1;
}

/**
* Returns whether the cursor index is before the first item.
*/
public function get beforeFirst():Boolean
{
return index < 0;
}

/**
* Moves the cursor index to the last item.
*/
public function seekLast():void
{
index = collection.length - 1;
}

/**
* Moves the cursor index to after the last item.
*/
public function seekAfterLast():void
{
index = collection.length;
}

/**
* Returns whether the cursor index is after the last item.
*/
public function get afterLast():Boolean
{
return index >= collection.length;
}

/**
* Returns whether an item exists before the current cursor index.
*/
public function get hasPrevious():Boolean
{
return index > 0;
}

/**
* Moves the cursor index to and returns the previous item.
*/
public function movePrevious():Object
{
index--;
return index > -1 ? collection[index] : null;
}

/**
* Returns whether an item exists after the current cursor index.
*/
public function get hasNext():Boolean
{
return index < collection.length - 1;
}

/**
* Moves the cursor index to and returns the next item.
*/
public function moveNext():Object
{
index++;
return index < collection.length ? collection[index] : null;
}

// Overrides of proxy to provide for...each support.

override flash_proxy function deleteProperty(name:*):Boolean {
return false;
}

override flash_proxy function getProperty(name:*):* {
return null;
}

override flash_proxy function hasProperty(name:*):Boolean {
return true;
}

override flash_proxy function nextNameIndex(index:int):int {
if (index > collection.length - 1)
return 0;
return index + 1;
}

override flash_proxy function nextName(index:int):String {
return String(index - 1);
}

override flash_proxy function nextValue(index:int):* {
return collection[index - 1];
}
}
}

And here are a few usage examples. Notice it supports for…each loops as well.

var vector:Vector.<User> = new Vector.<User>();
vector.push(new User('Bob'));
vector.push(new User('Jan'));
vector.push(new User('Sam'));

var cursor:VectorCursor = new VectorCursor(vector);

// Iterate from first to last.
while (!cursor.afterLast)
{
trace(cursor.current);
cursor.moveNext();
}

trace('----------');

// Iterate from last to first.
cursor.seekLast();
while (!cursor.beforeFirst)
{
trace(cursor.current);
cursor.movePrevious();
}

trace('----------');

// For...each example from first to last.
for each (var item:Object in cursor)
{
trace(item);
}
One clap, two clap, three clap, forty?

By clapping more or less, you can signal to us which stories really stand out.