Skip to content

Instantly share code, notes, and snippets.

@awerlang
Created January 5, 2015 16:42
Show Gist options
  • Save awerlang/7ce9ead90f82c0c1db08 to your computer and use it in GitHub Desktop.
Save awerlang/7ce9ead90f82c0c1db08 to your computer and use it in GitHub Desktop.
natural compare function
// benchmark: http://jsperf.com/natural-compare
"use strict";
function lexiSort(config) {
return function (a, b) {
if (typeof a === "number" && typeof b === "number")
return a - b;
if (a === null || b === null)
return NaN;
if (a === undefined || b === undefined)
return NaN;
if (Array.isArray(a) || Array.isArray(b))
return NaN;
if (typeof a === "object" || typeof b === "object") {
if (!config && !config.keyFunc)
return NaN;
if (typeof a === "object")
a = config.keyFunc(a);
if (typeof b === "object")
b = config.keyFunc(b);
}
if (typeof a !== "string" || typeof b !== "string")
return a - b;
if (a.length === 0 || b.length === 0)
return a.length - b.length;
var s1 = a, s2 = b, indexA = 0, indexB = 0, numberA, numberB, charA, charB, difference;
do {
numberA = 0;
while (indexA < s1.length) {
charA = s1[indexA];
indexA++;
if (!(charA >= "0" && charA <= "9"))
break;
numberA = numberA * 10 + parseInt(charA);
}
numberB = 0;
while (indexB < s2.length) {
charB = s2[indexB];
indexB++;
if (!(charB >= "0" && charB <= "9"))
break;
numberB = numberB * 10 + parseInt(charB);
}
if (charA === " " && charB === " ") {
while (indexA < s1.length && s1[indexA] === " ") {
indexA++;
}
while (indexB < s2.length && s2[indexB] === " ") {
indexB++;
}
}
difference = numberA - numberB;
if (difference !== 0)
return difference;
if (charA !== charB) {
if (charA === ".")
return -1;
if (charB === ".")
return 1;
return charA.toUpperCase().charCodeAt(0) - charB.toUpperCase().charCodeAt(0);
}
} while (indexA < s1.length && indexB < s2.length);
return (indexB - s2.length) - (indexA - s1.length);
};
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment