Much of programming involves managing arrays (lists) in some way, and there's broad consensus about the basic tools for creating and manipulating them. Arrays can be joined, pushed, popped, spliced, and reversed using much the same syntax in most major programming languages, with a few exceptions like INTERCAL and Python that use more eccentric terminology to do the same things.
For those of us used to Ruby and the syntactic sugar rush provided by methods like Enumerable.collect, .inject, .reject, and .select switching gears to get to grips with Javascript can induce the sorts of headaches caused by brutally mixed metaphors. Given Javascript's dynamic nature and its symbiosis with the DOM, we might expect more from the Javascript Array object than we get.
For example, sorting an array is one of those basic operations we expect to be available.
We even expect the language to do a little bit of magic, as Ruby does, determining what data type(s) the array's elements are and sorting accordingly when the array consists of all numbers or strings:
[3,1,21,2].sort
=> [1,2,3,21]
["badger","antelope","bison","wallaby"].sort
=> ["antelope", "badger", "bison", "wallaby"]
Ruby, of course, gives us its customary sort and sort! depending whether we want to change the array.
Javascript goes to great lengths to make sorting not work as you might expect. First, Array.sort() both changes the array, and returns the sorted version -- if you need to preserve the original order of your array, you'll need to copy it before sorting. Then, even though Javascript has no difficulty in determining the data types in arrays like the examples here, it insists on sorting them alphabetically.
var a = [3,1,21,2];
alert(a.sort());
=> [1,2,21,3]
alert(a);
=> [1,2,21,3]
This is even though it knows full well that these are numeric values:
alert(typeof(a[0]));
=> number
And to think some people say unkind things about Javascript.
Even with the Prototype library's indispensible Enumerable mixin, Javascript is still playing catch-up, but at least we can recreate the functionality we want.
Prototype's Enumerable.sortBy() method takes an iterator -- an anonymous function applied to each element in the Enumerable -- and sorts the array by the iterated elements. It's a useful function for playing all kinds of tricks. Sort by length-of-word, for example:
alert( ["badger","antelope","bison","wallaby"].sortBy(function(element) {return(element.length);}) );
=> ["bison","badger","wallaby","antelope"]
This method does not change the original array, as Javascript's native .sort() does. Another valuable feature is that it *does* automatically sort according to the elements' data type, so it is not necessary for the iterator to transform numeric values via parseInt or parseFloat (even though it might feel that it should be).
Now we can implement a numerical sort easily, if not too prettily:
alert([3,1,21,2].sortBy(function(element) { return(element);}) );
=> [1,2,3,21]
It seems a lot of palaver for what we're used to getting for free, but there it is.
Recent Comments