I'd like to share a trick I routinely use in C/C++ for qsort()
.
JS' sort() allows to specify a compare function. Create second array of the same length and fill it with increasing numbers from 0.
function stableSorted(array, compareFunction) {
compareFunction = compareFunction || defaultCompare;
var indicies = new Array(array.length);
for (var i = 0; i < indicies.length; i++)
indicies[i] = i;
This are indexes into the original array. We are going to sort the second array. Make a custom compare function.
indicies.sort(function(a, b)) {
It will get the two elements from the second array: use them as indexes into the original arrays and compare the elements.
var aValue = array[a], bValue = array[b];
var order = compareFunction(a, b);
if (order != 0)
return order;
If elements happen to be equal, then compare their indexes to make the order stable.
if (a < b)
return -1;
else
return 1;
});
After the sort(), the second array would contain indexes which you can use to access the elements of original array in stable sorted order.
var sorted = new Array(array.length);
for (var i = 0; i < sorted.length; i++)
sorted[i] = array[indicies[i]];
return sorted;
}
// The default comparison logic used by Array.sort(), if compareFunction is not provided:
function defaultCompare(a, b) {
a = String(a);
b = String(b);
if (a < b) return -1;
else if (a > b) return 1;
else return 0;
}
In general, stable sort algorithms are only maturing and still require more extra memory compared to the good ol' qsort. I guess that's why very few specs mandate stable sort.