portfolio | contact
October
Thursday the 9th

Complex dynamic array sorting

Thursday, 7:16 PM
Have you ever wanted to sort an array in a non-standard way? Have you ever wanted to sort an array of objects by one of the properties common between the objects in the array? Continue reading!

I will move through this topic as if you have no idea how awesome Array.sort() is. If you know some already, you may want to skip a bit.

Say we have an array that looks like this:
["A","a","C","c","B","b"]

When we sort it, we would expect: AaBbCc right? Well, I would anyway. Turns out we get ABCabc. Pretend you REALLY want AaBcCc, or some other non-standard sorting result. You can still use Array.sort()! It turns out that Array.sort() accepts a single argument. The expected argument is a function which will itself accept two arguments. The function should compare the two and then pass back -1, 0, or 1 depending on what you'd like to do. Return a value of 1 or greater if the first value should be first, a value of -1 or less if the second value should be first, or 0 if they are equal. This is allows us to sort an array of numbers (since by default, the sort function will sort numbers alphabetically - meaning 1,2,26,33,4,5,6 etc).

a quick and dirty mock up might look like this:
sortedArray = myArray.sort(function(a,b){return a-b});

awesome! Now we can sort by all manner of arbitrary and senseless rubrics. We could sort an array of strings but their length rather than alphabetically like so:
myArray.sort(function(a,b){return a.length-b.length});

Now, lets say that instead of an array of strings or numbers, we have an array of objects. [{object},{object},{object}] I don't know what would happen if you tried to sort them, but I would have to imagine nothing useful coming out the other end. In order to sort the objects, we need a rubric or a rule. If all the objects share a member value or property, we can use that and write a function like this:

myArray.sort(function(a,b){
valueA = a.price;
valueB = b.price;
if(valueA < valueB){return -1}
if(valueA > valueB){return 1}
return 0;
});


Omg this is getting exciting! Can you feel it? All of a sudden, huge arrays of complex objects can be thrown to the native javascript methods rather than writting your own cumbersome sorting functions. The problem I ran into is that if you want to sort your array by multiple dimensions, the sorting methods replicate like leporidae and before long, you've got pages of them (cause you'll need two for each dimension. One to sort ascending, and one to sort descending). Its too bad that Array.sort() wont pass two additional arguments to the sorting function - one for the member property and one for the direction.....

And then there comes a point in every boys life where he finally finds a reason to write a function which returns a function as the output.

i now present - getDynamicSortMethod()

function getDynamicSortMethod(sortProperty, direction){
var thisMethod = function(a,b){
var valueA = a[sortProperty];
var valueB = b[sortProperty];
if(typeof valueA != "number" && typeof valueA != "object"){
var valueA = a[sortProperty].toLowerCase();
var valueB = b[sortProperty].toLowerCase();
}
if(direction.toLowerCase() == "up"){
if (valueA < valueB) {return -1}
if (valueA > valueB) {return 1}
}else{
if (valueA > valueB) {return -1}
if (valueA < valueB) {return 1}
}
return 0;
}
return thisMethod;
}


we can then use this function to do all manner of crazy sorting! Assuming we had an array of objects like:
{
name: "A car",
price: 40000,
year: 2008,
maker: "Tesla",
otherData: "as needed"
}


We can perform the following sorting operations:
sortedArray = myCarInventory.sort(getDynamicSortMethod("maker","up"));
sortedArray = myCarInventory.sort(getDynamicSortMethod("price","down"));
sortedArray = myCarInventory.sort(getDynamicSortMethod("year","up"));


◄ back