I need to implement a function with the same behaviour as the default compare function of Array.prototype.sort
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/sort
After reading the documentation I stumbled upon this:
The default sort order is according to string Unicode code points.
What does this mean? Does it mean I convert every object to a string?
If so, assuming I have the array [2, "a", { hello: "world" }]
would these steps be correct?
[2, "a", { hello: "world" }]
to ["2", "a", '{ hello: "world" }']
How do I implement a compare function that given any object, behaves exactly as the compare function from sort?
Reading the ECMA specification:
I now believe that if comparefn
is undefined
, then they use this algorithm as a default:
http://www.ecma-international.org/ecma-262/6.0/#sec-sortcompare
Can someone confirm?
After reading the ECMA spec and asking around, I arrived to a defaultCompare
function that simulates the default behaviour of Array.prototype.sort()
in chrome:
const defaultCompare = ( x, y ) => {
//INFO: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/sort
//ECMA specification: http://www.ecma-international.org/ecma-262/6.0/#sec-sortcompare
if( x === undefined && y === undefined )
return 0;
if( x === undefined )
return 1;
if( y === undefined )
return -1;
const xString = toString(x);
const yString = toString(y);
if( xString < yString )
return -1;
if( xString > yString )
return 1;
return 0;
};
const toString = obj => {
//ECMA specification: http://www.ecma-international.org/ecma-262/6.0/#sec-tostring
if( obj === null )
return "null";
if( typeof obj === "boolean" || typeof obj === "number" )
return (obj).toString();
if( typeof obj === "string" )
return obj;
if( typeof obj === "symbol" )
throw new TypeError();
//we know we have an object. perhaps return JSON.stringify?
return (obj).toString();
};
module.exports = defaultCompare;
You can test this function like the following:
const arr = [ undefined, null, 3, 2, 'B', 'a', 'b', 'A',
{ hello: "world"}, { goodnight: 'moon'} ]
assertEql( arr.sort(), arr.sort(defaultCompare) ); //true
The outputs should be equal, provided you test them in the same browser.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With