Recipe 5.10.
Sorting or Reversing an Array
Problem
You want
to sort the elements of an
array.
Solution
Use the sort( ) method. For arrays of objects,
you can also use the sortOn( ) method.
Discussion
You can perform a simple sort on an array using
the sort( ) method. The sort( ) method, without any
parameters, sorts the elements of an array in ascending order.
Elements are sorted according to the Unicode code points of the
characters in the string (roughly alphabetical for Western European
languages).
var words:Array = ["tricycle", "relative", "aardvark", "jargon"];
words.sort( );
trace(words); // Displays: aardvark,jargon,relative,tricycle
The sort( ) method, by default, is very
useful if you want to sort the elements of an array in ascending,
alphabetical order. However, there are some caveats. Namely, the
sort is case-sensitive, and
it sorts numbers "alphabetically" instead of numerically.
Fortunately, ActionScript allows you to pass one of several
constants to the sort( ) method in order to sort with
different guidelines.
You sort an array in descending order using the
Array.DESCENDING
constant:
var words:Array = ["tricycle", "relative", "aardvark", "jargon"];
words.sort(Array.DESCENDING);
trace(words); // Displays: tricycle,relative,jargon,aardvark
As mentioned, the sort( ) method runs a
case-sensitive sort by default. It places elements starting with
uppercase characters before elements starting with lowercase
characters. The following illustrates the point:
var words:Array = ["Tricycle", "relative", "aardvark", "jargon"];
words.sort( );
trace(words); // Displays: Tricycle,aardvark,jargon,relative
You can use the Array.CASEINSENSITIVE constant to
run a case-insensitive sort:
var words:Array = ["Tricycle", "relative", "aardvark", "jargon"];
words.sort(Array.CASEINSENSITIVE);
trace(words); // Displays: aardvark,jargon,relative,Tricycle
When you sort an array of numbers, the values
are sorted according to the ASCII equivalents of the digits rather
than in numerical order. The following code illustrates the
point:
var scores:Array = [10, 2, 14, 5, 8, 20, 19, 6];
scores.sort( );
trace(scores); // Displays: 10,14,19,2,20,5,6,8
You can use the Array.NUMERIC constant with the
sort( ) method to sort an array of numbers numerically:
var scores:Array = [10, 2, 14, 5, 8, 20, 19, 6];
scores.sort(Array.NUMERIC);
trace(scores); // Displays: 2,5,6,8,10,14,19,20
There are two other possible constants you can
use with the sort( ) method: Array.UNIQUESORT and Array.RETURNINDEXEDARRAY. In some
situations you want to sort the array only if it contains unique
elements. In this case, use the Array.UNIQUESORT constant;
Flash only sorts the array if the elements are unique. Otherwise,
the sort( ) method returns 0, and the array is not
sorted:
var ranking:Array = [2,5,6,3,1,1,4,8,7,10,9];
var sortedRanking:Object = ranking.sort(Array.UNIQUESORT);
trace(sortedRanking); // Displays: 0
trace(ranking); // Displays: 2,5,6,3,1,1,4,8,7,10,9
Frequently, you may want to get the sorted order
of an array's elements, but you don't want to change the original
array because other parts of your application may depend on the
existing order. For example, if you have parallel arrays, and you
sort one array, its relationship with the other arrays is no longer
valid. In such scenarios the Array.RETURNINDEXEDARRAY
constant is very helpful. It allows you to return a new array
containing the indices of the elements of the original array in
sorted order, as illustrated in the following code:
var words:Array = ["tricycle", "relative", "aardvark", "jargon"];
var indices:Array = words.sort(Array.RETURNINDEXEDARRAY);
trace(words); // Displays: tricycle,relative,aardvark,jargon
trace(indices); // Displays: 2,3,1,0
for(var i:int = 0; i < words.length; i++) {
/* Displays:
aardvark
jargon
relative
tricycle
*/
trace(words[indices[i]]);
}
You aren't limited to one sort modifier at a
time. You can combine the combine the constants using the bitwise
OR operator (|).
The following code illustrates a case-insensitive, descending
sort:
var words:Array = ["Tricycle", "relative", "aardvark", "jargon"];
words.sort(Array.CASEINSENSITIVE | Array.DESCENDING);
trace(words); // Displays: Tricycle,relative,jargon,aardvark
Sometimes you want to reverse the order of the
elements in an array. The sort( ) method allows you to run
ascending, descending, case-sensitive, case-insensitive, and
numeric sorts, but it does not allow you to simply reverse the
order of the elements. Instead, you can use the reverse( ) method. The
reverse( ) method does just what its name suggests; it
reverses the order of the elements:
var words:Array = ["tricycle", "relative", "aardvark", "jargon"];
words.reverse( );
trace(words); // Displays: jargon,aardvark,relative,tricycle
The preceding portion of this recipe described
how to sort arrays in which the elements are strings or numbers.
You can also sort arrays of objects of any type using the
sortOn( ) method. The sortOn( ) method requires a
string parameter specifying the name of the property on which to
sort the elements:
var cars:Array = new Array();
cars.push({make: "Honda", year: 1997, color: "maroon"});
cars.push({make: "Chrysler", year: 2000, color: "beige"});
cars.push({make: "Mercedes", year: 1985, color: "blue"});
cars.push({make: "Fiat", year: 1983, color: "gray"});
// Sort the cars array according to the year property
// of each element.cars.sortOn("year");
for (var i:int = 0; i < cars.length; i++) {
/* Displays:
gray 1983 Fiat
blue 1985 Mercedes
maroon 1997 Honda
beige 2000 Chrysler
*/
trace(cars[i].color + "\t" +
cars[i].year + "\t" +
cars[i].make);
}
The sortOn( ) method also has the ability
to sort on more than one field. You can do so by specifying an
array of fields on which to sort. The elements are then sorted on
those fields in the specified order. To understand how it works,
take a look at the following examples:
var cars:Array = new Array( );
cars.push({make: "Honda", year: 1997, color: "maroon"});
cars.push({make: "Chrysler", year: 2000, color: "beige"});
cars.push({make: "Mercedes", year: 1985, color: "blue"});
cars.push({make: "Fiat", year: 1983, color: "gray"});
cars.push({make: "Honda", year: 1992, color: "silver"});
cars.push({make: "Chrysler", year: 1968, color: "gold"});
cars.push({make: "Mercedes", year: 1975, color: "green"});
cars.push({make: "Fiat", year: 1983, color: "black"});
cars.push({make: "Honda", year: 2001, color: "blue"});
cars.push({make: "Chrysler", year: 2004, color: "orange"});
cars.push({make: "Mercedes", year: 2000, color: "white"});
cars.push({make: "Fiat", year: 1975, color: "yellow"});
// Sort the cars array according to the year property
// of each element, then by the make.
cars.sortOn(["year", "make"]);
for (var i:int = 0; i < cars.length; i++) {
/* Displays:
gold 1968 Chrysler
yellow 1975 Fiat
green 1975 Mercedes
black 1983 Fiat
gray 1983 Fiat
blue 1985 Mercedes
silver 1992 Honda
maroon 1997 Honda
beige 2000 Chrysler
white 2000 Mercedes
blue 2001 Honda
orange 2004 Chrysler
*/
trace(cars[i].color + "\t" +
cars[i].year + "\t" +
cars[i].make);
}
The next example sorts the same array first by
make, then by yearnotice what the effect is:
cars.sortOn(["make", "year"]);
for (var i:int = 0; i < cars.length; i++) {
/* Displays:
gold 1968 Chrysler
beige 2000 Chrysler
orange 2004 Chrysler
yellow 1975 Fiat
black 1983 Fiat
gray 1983 Fiat
silver 1992 Honda
maroon 1997 Honda
blue 2001 Honda
green 1975 Mercedes
blue 1985 Mercedes
white 2000 Mercedes
*/
trace(cars[i].color + "\t" +
cars[i].year + "\t" +
cars[i].make);
}
As with the sort( ) method, the
sortOn( ) method supports sort modifiers. You can use the
Array constants to sort in descending, case-insensitive, and
numeric order. You can also, as with the sort( ) method, run
a unique sort and return an array of sorted indices rather than
affecting the original array. The following example sorts
cars in descending order:
cars.sortOn("year", Array.DESCENDING);
for (var i:int = 0; i < cars.length; i++) {
/* Displays:
beige 2000 Chrysler
maroon 1997 Honda
blue 1985 Mercedes
gray 1983 Fiat
*/
trace(cars[i].color + "\t" +
cars[i].year + "\t" +
cars[i].make);
}
Sorted arrays can be useful in many scenarios.
For example, if you want to display the elements of an array in a
UI component or a text field, you often want to list the elements
in alphabetical order.
|
Unless you use the
Array.RETURNINDEXEDARRAY constant, the sort( ) and
sortOn( ) methods make changes to the order of the original
array; they do not return a new array.
|
|
See Also
Recipe
5.8 to make aseparate copy of an array on which you can perform
destructive operations. Recipe
5.11 for details on custom sorting.
|