start page | rating of books | rating of authors | reviews | copyrights

Book HomeActionScript: The Definitive GuideSearch this book

11.9. General Array-Manipulation Tools

Earlier we saw how array methods can be used to remove elements from and add elements to arrays. ActionScript also offers built-in methods for reordering and sorting elements, converting array elements to strings, and extracting arrays from other arrays.

11.9.1. The reverse( ) Method

As its name suggests, the reverse( ) method reverses the order of the elements of an array. Simple, but impressive. Here's the syntax:

arrayName.reverse( )

And here are the impressive results:

var x = [1, 2, 3, 4];
x.reverse( );
trace(x);  // Displays: "4,3,2,1"

We typically use reverse( ) to reorder a sorted list. For example, if we have a list of products sorted by ascending price, we can display them from least to most expensive, or we can reverse the list to display them from most to least expensive.

Reader Exercise: Try to write your own custom function to reverse the elements in an array. Not only is it harder than it looks, you'll most likely find that the built-in reverse( ) method is substantially faster.

11.9.2. The sort( ) Method

The sort( ) method rearranges the sequence of elements in an array according to an arbitrary rule that we provide. If we provide no rule, sort( ) places the elements in (roughly) alphabetical order by default. Sorting an array alphabetically is really easy, so let's see how that works first:

arrayName.sort( )

When we invoke an array's sort( ) method with no arguments, its elements are temporarily converted to strings and sorted according to their code points as shown in Appendix B, "Latin 1 Character Repertoire and Keycodes" (see "Character order and alphabetic comparisons" in Chapter 4, "Primitive Datatypes", for important details):

// This works as expected...
var animals = ["zebra", "ape"];
animals.sort( );
trace(animals);  // Displays: "ape,zebra"
                 // Cool! What a handy little method.

// Watch out, the sort order is not strictly alphabetical...The
// capital "Z" in zebra comes before the lowercase "a" in "ape".
var animals = ["Zebra", "ape"];
animals.sort( );
trace(animals);  // Displays: "Zebra,ape". Oops. See Appendix B.

We can also use sort( ) to organize array elements according to a rule of our own choosing. This technique is a little trickier to work with, but quite powerful. We start by creating a compare function that dictates how the interpreter should sort any two elements of an array. We then pass that function to the sort( ) method when we call it, like this:

arrayName.sort(compareFunction)

where compareFunction is the name of the function that tells the interpreter how to make its sorting decisions.

To build a compare function, we start with a new function that accepts two arguments (these represent any two elements in the array). In the function's body, we determine, however we see fit, which of the elements we'd like to appear earlier in the element list after a sort( ). If we want the first element to appear before the second element, we return a negative number from our function. If we want the first element to appear after the second element, we return a positive number from our function. If we want the elements to be left in the same positions, we return from our function. In pseudocode, the approach generically looks like this:

function compareElements (element1, element2) {
  if (element1 should appear before element2) {
    return -1;
  } else if (element1 should appear after element2) {
    return 1;
  } else {
    return 0;  // The elements should be left alone
  }
}

For example, to put elements in ascending numeric order, we could use a function like this:

function sortAscendingNumbers (element1, element2) {
  if (element1 < element2) {
    return -1;
  } else if (element1 > element2) {
    return 1;
  } else {
    return 0;  // The elements are equal
  }
}

// Now that our compare function is ready, let's try it out
var x = [34, 55, 33, 1, 100];
x.sort(sortAscendingNumbers);
trace(x);    // Displays: "1,33,34,55,100"

Numeric-sort functions can actually be phrased much more succinctly. The preceding sortAscendingNumbers( ) function could be written as:

function sortAscendingNumbers (element1, element2) {
  return element1 - element2;
}

In our optimized version, a negative number is returned if element1 is less than element2, a positive number is returned if element1 is greater than element2, and a is returned if the two are equal. Now that's elegant! Here is a version to perform a descending sort:

function sortDescendingNumbers (element1, element2) {
  return element2 - element1;
}

Example 11-6 shows a compare function that adjusts the default alphabetic comparison behavior of sort( ) so that upper- and lowercase letters are sorted without regard to case.

Example 11-6. A Case-Insensitive Alphabetic Array Sort

var animals = ["Zebra", "ape"];

function sortAscendingAlpha (element1, element2) {
	return (element2.toLowerCase() < element1.toLowerCase( ));
}

animals.sort(sortAscendingAlpha);
trace(animals);  // Displays: "ape,Zebra"

Of course, the comparison does not always have to involve simple strings and numbers. Here we sort an array of movie clips in ascending order, according to their pixel area:

var clips = [square1, square2, square3];

function sortByClipArea (clip1, clip2) {
  clip1area = clip1._width * clip1._height;
  clip2area = clip2._width * clip2._height
  return clip1area - clip2area;
}

clips.sort(sortByClipArea);

That's a mighty fine sortin' machine!

11.9.3. The slice( ) Method

Something of a subset of splice( ), slice( ) retrieves a series of elements from an array. Unlike splice( ), slice( ) only retrieves elements. It creates a new array and does not affect the array on which it is invoked. The slice( ) method has the following syntax:

origArray.slice(startIndex, endIndex)

where startIndex specifies the first element to retrieve and endIndex specifies the element after the last element we want to retrieve. The slice( ) method returns a new array containing a copy of the series of elements from origArray[startIndex] to origArray[endIndex - 1]. If endIndex is omitted, it defaults to origArray.length and the returned array contains the elements from origArray[startIndex] through origArray[origArray.length-1]. Here are a couple of examples:

var myList = ["a", "b", "c", "d", "e", "f"];
myList.slice(1, 3);  // Returns ["b", "c"], not ["b", "c", "d"]
myList.slice(2);     // Returns ["c", "d", "e", "f"]

11.9.4. The join( ) Method

We can use join( ) to produce a string that represents all the elements of an array. The join( ) method starts by converting each element of the specified array to a string. Empty elements are converted to the empty string (""). Then join( ) concatenates all the strings into one long string, separating them with a character (or series of characters) called a delimiter. Finally, join( ) returns the resulting string. The syntax of join( ) is:

arrayName.join(delimiter)

where delimiter is the string used to separate the converted elements of arrayName. If unspecified, delimiter defaults to a comma. The result of a join( ) statement is easiest to understand through an example:

var siteSections = ["animation", "short films", "games"];

// Sets siteTitle to "animation>> short films>> games"
var siteTitle = siteSections.join(">> ");

// Sets siteTitle to "animation:short films:games"
var siteTitle = siteSections.join(":");

Note that join( ) does not modify the array upon which it is invoked. Instead, it returns a string based on that array.

When called without a delimiter argument, join( ) behaves exactly like toString( ). Because toString( ) does not add a space after the comma it uses to delimit elements, we may wish to use join( ) if we want nicely formatted output:

var x = [1, 2, 3];
trace(x.join(", "));  // Displays: "1, 2, 3" instead of "1,2,3"

The join( ) method has a potentially surprising result when used on an array that contains elements which are themselves arrays. Since join( ) converts elements to strings, and arrays are converted to strings via their toString( ) method, nested arrays are converted to strings using a comma delimiter, not the delimiter supplied to join( ) as an argument. In other words, any delimiter supplied to join( ) doesn't affect nested arrays. For example:

var x = [1, [2, 3, 4], 5];
x.join("|");  // Returns "1|2,3,4|5"

11.9.5. The toString( ) Method

As we'll learn in Chapter 12, "Objects and Classes", toString( ) is a universal object method that returns a string representation of any object upon which it is invoked. In the case of an Array object, the toString( ) method returns a list of the array's elements converted to strings and separated by commas. The toString( ) method may be called explicitly:

arrayName.toString( )

Typically, we don't use toString( ) explicitly; rather, it is invoked automatically whenever arrayName is used in a string context. For example, when we write trace(arrayName), a list of comma-separated values appears in the Output window; trace(arrayName) is equivalent to trace(arrayName.toString( )). The toString( ) method is often helpful during debugging when we need a quick, unformatted look at the elements of an array. For example:

var sites = ["www.moock.org", "www.macromedia.com", "www.oreilly.com"];
// Display our array in a text field
debugOutput = "the sites array is " + sites.toString( );

11.9.6. Arrays as Objects

Once you've read Chapter 12, "Objects and Classes", you should recognize that arrays are a type of object, specifically instances of the Array class. As with other objects, array objects can have properties added to them. When we add named elements to an array, we're really just adding properties to an Array object. However, as we learned earlier, to use the built-in methods of the Array class we must work with numbered elements.

In Chapter 9, "Functions", we saw a useful "array-object" hybrid, the arguments object, that combined numbered elements with properties. (Recall that the arguments object has a callee property and also stores an array of parameters as array elements.) Now we can see that all arrays contain their numbered list of elements, plus the built-in property length, plus any custom properties we add.



Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.