Sorting Tip – Performing numeric and alphabetic sorting

Ever want to slap yourself for doing something the stupid way? I recently did. I was using the Array object’s built-in sort() method to sort a list, then (when I saw the result) realized that the list was sorted exactly backwards from what I wanted. I was just about to write a custom comparison routine (which of course you can pass to the built-in sort() method, if you want) when I realized there was no need to do that. All you have to do to get the sorting done in reverse order is call reverse() on the sorted array. Thus:



var lohi = ['April','June','May','July'].sort(); // var hilo =

['April','June','May','July'].sort().reverse();

Of course, if you’re sorting numeric values, you have to write your own comparison

routine, because JavaScript interprets array members as strings for sorting purposes (doh!).

Hence:


var lohi = [111,4,22,3].sort(); // Whoa! 111,22,3,4 var hilo =

[111,4,22,3].sort().reverse(); // 4,3,22,111function myCompare(a,b) { return

Number(a) - Number(b); }var lohi = [111,4,22,3].sort(myCompare); // Yes!

3,4,22,111var hilo = [111,4,22,3].sort(myCompare).reverse(); // 111,22,4,3

A numeric sorting example

But what if you’ve got a bunch of values that look like ’33:red’,’12:blue’,’8:black’,

etc., and you want to do a numeric sort on the characters preceding the colon in each item?

Remember, if you don’t use a custom compare routine, you’ll get just an alphabetic sorting.

Here’s one way to do a true numeric sort based on the numbers 33, 12, 8, etc.:

function myCompare(a,b) { 'var aa = a.match(/d+/);'var bb 

= b.match(/d+/);'return Number(aa[0]) - Number(bb[0]); }

The match method

The match() method of the String object looks for a match of the regular

expression in its argument to the string in the parent object. In this case, we look for a

match against one or more digits (the slash-d means ‘digit’ and the plus-sign means ‘one or

more of these in a row’). The return value from match() is an Array object, the

zeroth element of which is the matching text that was found (or null, if none was found).

But we want to be sure to cast that zeroth element to a Number, and return the comparison

result.

As you can imagine, if you’re good with regular expressions you can accomplish some

pretty amazing feats with the Array object’s built-in sort() routine (which, by the

way, is built on a qsort, or quicksort, algorithm). You do pay a stiff

performance penalty, though, if you get carried away with regexes inside the compare

routine. If your sort involves more than a couple hundred items, you’ll probably want to try

to move all the regex operations into a separate ‘pre-sort’ routine (where they’ll at least

execute in order-N time, instead of N-log-N), then do the sort, then rebuild the data.

You May Also Like

About the Author: Kas Thomas

Leave a Reply