That's a common pattern for sorting APIs. If the returned value is 0, that means that the items are (for the purposes of ordering) equal.
In practice, the behavior of a sort function with equal keys is of some importance. A sort that leaves entries in the order they were in (relative to each other) when the keys are equal is called a stable sort. In JavaScript, the .sort()
API is explicitly specified as not necessarily being stable. That means that the sort function might leave you with an array wherein two elements that compared as equal are swapped when the sort is complete.
That behavior has an effect on how you use the .sort()
function. Let's say you have a list of objects:
var list = [{
firstName: "Louis",
lastName: "Adams",
// ...
}, {
// ...
}];
So, objects with a first name field and a last name field. If the JavaScript .sort()
API were required to be stable, then you could sort the list in a way that people would expect it to be sorted by doing this:
function ocompare(key, o1, o2) {
return o1[key] < o2[key] ? -1 :
o1[key] > o2[key] ? 1 :
0;
}
list.sort(function(o1, o2) {
return ocompare("firstName", o1, o2);
});
list.sort(function(o1, o2) {
return ocompare("lastName", o1, o2);
});
That is, you could sort on the first name, and then sort on the last name, and you'd have a list sorted by last names, and you'd be sure that "Adams, John" would be in the list before "Adams, Zach". (Note that the first thing we sort on is the less important key.)
However, the JavaScript .sort()
API is not necessarily stable, so you can't rely on that. Instead, you have to do all the ordering comparisons you want in a single pass through .sort()
:
function ocompare(o1, o2) {
var keys = [];
for (var i = 2; i < arguments.length; keys[i] = arguments[i], ++i);
for (i = 0; i < keys.length; ++i) {
if (o1[keys[i]] < o2[keys[i]])
return -1;
if (o1[keys[i]] > o2[keys[i]])
return 1;
}
return 0;
}
list.sort(function(o1, o2) {
return ocompare(o1, o2, "lastName", "firstName");
});
Note that this (while a bit more involved) might be faster than doing the two-pass approach that relies on a stable sort, because no comparison is necessary when the last name fields differ.