New Array Methods in Actionscript 3

devon o wolfgang


<ARRAYS>
In the beginning was the Word. And the Word was grouped with other Words to form arrays...

Yeah, okay. So that may be a bit melodramatic, but an application without arrays is like a class without methods (or clouds without water) - they are just that important. Actionscript 2 provided the concat(), join(), pop(), push(), reverse(), shift(), slice(), sort(), sortOn(), splice(), and unshift() methods to manipulate arrays. In addition to those, Actionscript 3 provides seven new very powerful methods to consider: every(), filter(), forEach(), indexOf(), lastIndexOf(), map(), and some(). Undocumented in the Flex 2 documentation, they have now been disclosed in the revamped Adobe Actionscript 3 livedocs. This is just a quick look at what these new Array methods do and when and how to use them.

INDEXOF/LASTINDEXOF:
when: You want to determine if an array contains a specified element.

what: These two methods work much the same way String.indexOf() works. These methods take two arguments, a value to search for and a (optional) beginning index number. The methods will return an integer value which is either the index number of the found element or a -1 if the element is not found. While indexOf() will start searching at the beginning of the array and return the index number of the first found element, lastIndexOf() will start searching at the end of the array and return the index number of the first found element (working backwards).

how:
Find the index value of 7 in an array of numbers with Array.indexOf():

package {
	
	import flash.display.Sprite;
	
	public class ArrayTest extends Sprite {
		
		private var _testArray:Array = new Array(5, 6, 7, 8, 9, 8, 7, 6);
		
		public function ArrayTest() {
			
			// traces 2 
			trace (_testArray.indexOf(7));
			
		}
	}	
}

Find the index value of 7 in an array of numbers with Array.lastIndexOf():

package {
	
	import flash.display.Sprite;
	
	public class ArrayTest extends Sprite {
		
		private var _testArray:Array = new Array(5, 6, 7, 8, 9, 8, 7, 6);
		
		public function ArrayTest() {
			
			// traces 6 
			trace (_testArray.lastIndexOf(7));
			
		}
	}	
}

Search for a nonexistent element with Array.indexOf():

package {
	
	import flash.display.Sprite;
	
	public class ArrayTest extends Sprite {
		
		private var _testArray:Array = new Array(5, 6, 7, 8, 9, 8, 7, 6);
		
		public function ArrayTest() {
			
			// traces -1 
			trace (_testArray.indexOf(3));
			
		}
	}	
}

EVERY/SOME:
when: You want to determine if every (Array.every()) or at least one (Array.some()) element in an array meets certain criteria.

what: These two methods accept two parameters, the name of a method to call which will specify your test criteria and an (optional) object which defines the scope in which the method resides. Each method will return a Boolean true or false depending on whether or not the specified criteria is met. The method which contains the test criteria will accept three arguments, an element of the array, the index of that particular element, and a reference to the array itself. This test method should have a Boolean for a return type.

how:
Test to see if every element in an array of numbers is less than 7 with Array.every():

package {
	
	import flash.display.Sprite;
	
	public class ArrayTest extends Sprite {
		
		private var _testArray:Array = new Array(5, 6, 7, 8, 9);
		
		public function ArrayTest() {
			
			// traces FALSE
			trace (_testArray.every(isBelowSeven));
			
		}
		
		private function isBelowSeven(element:int, index:int, array:Array):Boolean {
			return (element < 7);
		}
	}
	
}

Test to see if some (or one) elements in an array of numbers are (is) less than 7 with Array.some():

package {
	
	import flash.display.Sprite;
	
	public class ArrayTest extends Sprite {
		
		private var _testArray:Array = new Array(5, 6, 7, 8, 9);
		
		public function ArrayTest() {
			
			// traces TRUE
			trace (_testArray.some(isBelowSeven));
			
		}
		
		private function isBelowSeven(element:int, index:int, array:Array):Boolean {
			return (element < 7);
		}
	}
	
}

Test to see if every element in an array is a type of number with Array.every():

package {
	
	import flash.display.Sprite;
	
	public class ArrayTest extends Sprite {
		
		private var _testArray:Array = new Array(5, 6, 7, "some string", new Object());
		
		public function ArrayTest() {
			
			// traces FALSE
			trace (_testArray.every(isNumerical));
			
		}
		
		private function isNumerical(element:*, index:int, array:Array):Boolean {
			return (element as Number);
		}
	}
	
}

Test to see if some (or one) of those elements in the same array are a type of string with Array.some():

package {
	
	import flash.display.Sprite;
	
	public class ArrayTest extends Sprite {
		
		private var _testArray:Array = new Array(5, 6, 7, "some string", new Object());
		
		public function ArrayTest() {
			
			// traces TRUE
			trace (_testArray.some(isString));
			
		}
		
		private function isString(element:*, index:int, array:Array):Boolean {
			return (element as String);
		}
	}
	
}

FILTER:
when: You want to create a new array from elements in a given array that match certain criteria.

what: This method accepts two parameters, the name of a method to call which will specify your test criteria and an (optional) object which defines the scope in which the method resides. This method will return a new array that contains each element that tests as true according to a test method. The method which contains the test criteria will accept three arguments, an element of the array, the index of that particular element, and a reference to the array itself. This method should have a Boolean for a return type (very similar to as above).

how:
Create an array of numbers that are less than 7 from an array of various numbers with Array.filter():

package {
	
	import flash.display.Sprite;
	
	public class ArrayTest extends Sprite {
		
		private var _testArray:Array = new Array(5, 6, 7, 8, 9);
		
		public function ArrayTest() {
			
			var newArray:Array = _testArray.filter(isBelowSeven);
			// traces 5,6
			trace (newArray);
			
		}
		
		private function isBelowSeven(element:int, index:int, array:Array):Boolean {
			return (element < 7);
		}
	}
	
}

Create an array of objects with a testProperty property of true with Array.filter():

package {
	
	import flash.display.Sprite;
	
	public class ArrayTest extends Sprite {
		
		private var _testArray:Array = new Array({testProperty:true}, {testProperty:true}, {testProperty:false}, {testProperty:false});
		
		public function ArrayTest() {

			var newArray:Array = _testArray.filter(isTestProperty);
			// traces 2
			trace (newArray.length);
			
		}
		
		private function isTestProperty(element:Object, index:int, array:Array):Boolean {
			return (element.testProperty);
		}
	}	
}

MAP:
when: You want to create a new array from elements in a given array after performing a function on those items in the original array.

what: This method is very similar to the Array.filter() method, however, rather than performing a true/false test on the items in the array, this method will alter the items of the array according to a particular method.

how:
Create an array of upper case strings from an array of lower case strings:

package {
	
	import flash.display.Sprite;
	
	public class ArrayTest extends Sprite {
		
		private var _testArray:Array = new Array("one", "two", "three", "four");
		
		public function ArrayTest() {

			var newArray:Array = _testArray.map(arrayToUpperCase);
			
			// traces ONE,TWO,THREE,FOUR
			trace (newArray);
			
		}
		
		private function arrayToUpperCase(element:String, index:int, array:Array):String {
			return (element.toUpperCase());
		}
	}	
}

Create an array of numbers by adding 7 to each element in an original array of numbers:

package {
	
	import flash.display.Sprite;
	
	public class ArrayTest extends Sprite {
		
		private var _testArray:Array = new Array(1, 2, 3, 4);
		
		public function ArrayTest() {

			var newArray:Array = _testArray.map(addSeven);
			
			// traces 8,9,10,11
			trace (newArray);
			
		}
		
		private function addSeven(element:Number, index:int, array:Array):Number {
			return (element + 7);
		}
	}	
}

FOREACH:
when: You want to call a particular method for each element in an array.

what: Perhaps the most powerful of the new method additions, this, like the last two methods, calls a method for each item in an array. Unlike the last two, however, there is no return type required - this simply calls a method for each item in an array.

how:
Create three red movieclips that trace the value "one", "two", or "three" when you click on them:

package {
	
	import flash.display.Sprite;
	import flash.display.MovieClip;
	import flash.events.MouseEvent;
	
	public class ArrayTest extends Sprite {
		
		private var _testArray:Array = new Array("one", "two", "three");
		
		public function ArrayTest() {
			
			_testArray.forEach(addCircle);
			
		}
		
		private function addCircle(element:String, index:int, array:Array):void {
			var circle_mc:MovieClip = new MovieClip();
			circle_mc.graphics.beginFill(0x660000);
			circle_mc.graphics.drawCircle((index * 60) + 50, 60, 25);
			circle_mc.graphics.endFill();
			circle_mc.dynProperty = element;
			circle_mc.buttonMode = true;
			circle_mc.addEventListener(MouseEvent.CLICK, onClick);
			addChild(circle_mc);
		}
		
		private function onClick(evt:MouseEvent):void {
			trace (evt.target.dynProperty);
		}
	}	
}

</ARRAYS>
Hopefully this quick look at the new Actionscript 3 array methods proved useful. In AS2 the type of functionality provided by these methods required some rather bloated and/or (at times) complex for or for...in loops to achieve the same desired effect. These new methods are a great addition to this latest version of Actionscript.