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.




ActionScript 3. 0 Cookbook
ActionScript 3.0 Cookbook: Solutions for Flash Platform and Flex Application Developers
ISBN: 0596526954
EAN: 2147483647
Year: 2007
Pages: 351

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net