Thursday, July 31, 2008

Sorting a numbered list

One task that's quite common is the sorting of data in an array. But there are some pitfalls to bear in mind, particularly when it comes to sorting numbers.

For example, take the following simple list and apply a sort:


var list:Array = [5, 10, 2, 21, 1, 15];
list.sort();
trace(list);
// outputs [1, 10, 15, 2, 21, 5]

Yikes...that didn't go exactly according to plan! So what happened? By default, the Array.sort() method converts numbers to strings before they're sorted, and then it sorts them according to their Unicode value.

Fortunately, Flash provides an option to perform a numeric sort on an array containing numbers:


var list:Array = [5, 10, 2, 21, 1, 15];
list.sort(Array.NUMERIC);
trace(list);
// outputs [1, 2, 5, 10, 15, 21]

Flash treats the contents of the array as numeric values and performs a correct sort. Which is fine, but what if the contents of the array are already stored as strings?


var list:Array = ["5", "10", "2", "21", "1", "15"];
list.sort(Array.NUMERIC);
trace(list);
// // outputs [1, 10, 15, 2, 21, 5]

Uh-oh, it looks like we're back to square one again!

Fortunately, it's easy to create a function that can correct this default behaviour by comparing each individual element in the array:


function compare(a, b) {
return a - b;
}

var list:Array = ["5", "10", "2", "21", "1", "15"];
list.sort(compare);
trace (list);
// outputs [1, 2, 5, 10, 15, 21]

The same function works with numbers too:


var list:Array = [5, 10, 2, 21, 1, 15];
list.sort(compare);
trace (list);
// outputs [1, 2, 5, 10, 15, 21]

And it will even perform a correct numerical sort with a mix of numbers and strings:


var list:Array = [5, "10", 2, "21", "1", 15];
list.sort(compare);
trace (list);
// outputs [1, 2, 5, 10, 15, 21]

If you want to reverse the order of your sort, the function handles that too; just swap the arguments around before they're returned:


function reverse(a, b) {
return b - a;
}

No comments: