Posts Tagged ‘object’

Sorted

Tuesday, February 9th, 2010

One of the problems I had to solve when writing my new jQuery listSplitter plugin was sorting an array of arrays/multidimensional array by one given column, eg

testArray = [[a, b], [b, a]];

How would you sort by the second column of the array?

I’m not sure if mine is the best solution, but here it is (it also works for an array of objects as well as an array of arrays):

/**
* sorts an array of arrays or objects using a specified column/property
*
* @param column (str/int) - the name/index of the column to use for sorting
* @param sortFunction (func) - the sort function to use for sorting (sort functions
*                             that can be used by array.sort() will also work here)
* @return array
*/
Array.prototype.sortByColumn = function(column, sortFunction) {
  return this.sort(function(a,b) {
    var testArray = [a[column], b[column]];
    testArray = (sortFunction) ? testArray.sort(sortFunction) : testArray.sort();
    return (testArray[0] == a[column]) ? -1 : 1;
  });
}

And to apply it to an array use it similarly to the array.sort() method, eg

myArray.sortByColumn(5);//sort alphabetically by column 5 of the array
myArray.sortByColumn('title', sortByLength); //sort by length of title attribute
function sortByLength(a,b) {
   return a.length - b.length;
}
myArray.sortByColumn('price',function(a,b){return a - b}); // sort by price

How it works

It runs the normal array.sort() method, but uses as its sort function a clever little function which picks out the values to be sorted by, creates a new test array out of these values and sorts it. Using the ternary operator, it checks if the test array is unchanged after this sort. If it is unchanged it means that the items in the original array are already in the right order so no change is made, otherwise they are swapped in the original array too.

Immunodeficiency

Tuesday, January 26th, 2010

I just solvedĀ  a bug which stemmed from the fact I forgot that javascript is a referential language, i.e. if you have a variable and you set another variable equal to it then it doesn’t in general clone the original variable, but merely just points both variables towards the same underlying object. This only applies to Arrays and Objects though, and to prove it here is a little demo (it turns out you can embed javascript straight into wordpress posts now!)

Irritatingly, if you have a bug which is caused by forgetting this principle then this will also make it hard to debug because it also affects how firebug reports information to you. When you console.log() an object or an array, firebug does the same as javascript – it creates a reference to an underlying object in the DOM. So, if you’ve been logging an object repeatedly in order to pinpoint when a rogue change takes place firebug will consistently provide you with references to the object as it is after your script’s finished running – not much use.

However, there is an easy way out*. console has methods other than .log(), and possibly the most useful is console.dir(). console.dir() takes a snapshot of any object or array, printing out each of its properties without maintaining a reference to the underlying object, and therefore giving a you a snapshot of an object as it is at the time.

*And a hard way (console.log() the properties of an object individually), which is how I resolved my bug, beforeĀ  looked into what other methods console had