15.4.4.11 Array.prototype.sort(comparefn)

2010-07-05

array Array.prototype.sort([comparefn:function])

Sorts the elements of this array in place.

The sort is not required to be "stable". Elements which are equal don't have to remain in the same order.

The comparefn parameter should be a function accepting two arguments, x and y. It should return a negative value if x > y, zero if x=y and positive if x>y.

The result of the sort is implementation specific if:
- the compare function is not "consistent" (two non-NaN numbers always produce same result, function doesnt alter this and the function respects reflexivity, symmetry and transitivity of =, < and >).
- this array is sparse (is missing at least one index below length as an own property) and at least one missing index can be found on the protypal chain.
- this array is sparse and it has [[Extensible]] property set to false
- has a nonnegative index lower than length that is a data property and whose [[Configurable]] attribute is false.
- any nonnegative index lower than length is a data property and has [[Configurable]] set to false.

The this value is coerced into an object.

The actual algorithm to sort is not given, only that it can use [[Get]], [[Put]], [[Delete]] (all with Throw parameter true) and SortCompare (below). And if this array is not sparse the [[Delete]] method should not be called. This array is returned (sorted).

The returned array may introduce no new values (all index properties on the array before the sort should still exist after the sort, the number of missing properties should also be equal and the length property must not be changed). And the returned array should have one property before another if the result of the given compare function returns negative for them when given in that order.

The given restrictions ensure that the given compare function divides the array into "equivalence classes" and that these classes are totally "ordered".

The SortCompare function in the specification assumes obj to be the array. We'll pass it on as a parameter for clarity.

Note that SortCompare calls the comparefn function that was passed on to sort. However, SortCompare can already make a decision before even calling comparefn, specifically on undefined or non-existent properties.

int SortCompare(i:int, j:int, comparefn:function|undefined, array:object) throw TypeError

Code: (Meta Ecma)
function SortCompare(j, k, comparefn, array) {
// array is coerced into an object in the spec only once!
//array = ToObject(array);
var jString = ToString(j);
var kString = ToString(k);
var hasj = array.[[HasProperty]](jString);
var hask = array.[[HasProperty]](kString);
if (!hasj && !hask) return +0;
if (!hasj) return 1;
if (!hask) return -1;
var x = obj.[[Get]](jString);
var y = obj.[[Get]](kString);
if (x === undefined && x === y) return +0;
if (x === undefined) return 1;
if (y === undefined) return -1;
if (comparefn !== undefined) {
if (!IsCallable(comparefn)) throw TypeError;
return comparefn.[[Call]](undefined, [x, y]); // todo: list or individual parameters?
}
var xString = Tostring(x);
var yString = Tostring(y);
if (xString < ystring) return -1;
if (xString > yString) return 1;
return +0;
}

Note undefined elements are always sorted to the end of the array, followed by non-existent elements.