JavaScript
//Map implementation for older browsers
[].map||(Array.prototype.map=function(a){for(var b=this,c=b.length,d=[],e=0,f;e<b;)d[e]=e in b?a.call(arguments[1],b[e],e++,b):f;return d})
!function() {
function _dynamicSortMultiple(attr) {
var props = arguments;
return function (obj1, obj2) {
var i = 0, result = 0, numberOfProperties = props.length;
/* try getting a different result from 0 (equal)
* as long as we have extra properties to compare
*/
while(result === 0 && i < numberOfProperties) {
result = _dynamicSort(props[i])(obj1, obj2);
i++;
}
return result;
}
}
function _dynamicSort(property) {
var sortOrder = 1;
if(property[0] === "-") {
sortOrder = -1;
property = property.substr(1, property.length - 1);
}
return function (a,b) {
var result = (a[property] < b[property]) ? -1 : (a[property] > b[property]) ? 1 : 0;
return result * sortOrder;
}
}
Array.prototype.sortBy = function() {
return this.sort(_dynamicSortMultiple.apply(null, arguments));
}
}();
var arr = [
{a:"a",b:"a",c:"a"},
{a:"b",b:"c",c:"b"},
{a:"b",b:"a",c:"a"},
{a:"b",b:"a",c:"b"},
{a:"b",b:"b",c:"a"},
{a:"b",b:"b",c:"b"},
{a:"b",b:"c",c:"a"},
{a:"b",b:"b",c:"b"},
{a:"b",b:"c",c:"a"},
{a:"b",b:"b",c:"b"},
{a:"b",b:"c",c:"a"},
{a:"c",b:"d",c:"b"},
{a:"d",b:"b",c:"b"},
{a:"c",b:"b",c:"d"},
{a:"x",b:"c",c:"a"}];
document.getElementById("res").innerText = "result:\na b c\n-----\n" + arr
.sortBy("c","b","a")
.map(function(val, i) {return [val["a"], val["b"], val["c"]].join(" ")})
.join("\n");