Skip to content

Instantly share code, notes, and snippets.

@simonklee
Last active August 29, 2015 14:15
Show Gist options
  • Save simonklee/537d724734b43d84b14a to your computer and use it in GitHub Desktop.
Save simonklee/537d724734b43d84b14a to your computer and use it in GitHub Desktop.
sort
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>sort</title>
<script>
function isNumeric(input) {
return (input - 0) == input && (''+input).trim().length > 0;
}
// returns the index of the first non-numeric index (inclusive)
function alphIndex(str) {
var n = 0;
while(n < str.length && isNumeric(str.charAt(n)))
n++;
return n;
}
// returns the index of the first numeric index (inclusive)
function numIndex(str) {
var n = 0;
while(n < str.length && !isNumeric(str.charAt(n)))
n++;
return n;
}
function compare(a, b) {
a = String(a), b = String(b);
var i = 0;
var aN = a.length;
var bN = b.length;
var N = Math.min(aN, bN);
if (aN == 0 && bN == 0) return 0;
if (aN == 0) return -1;
if (bN == 0) return 1;
while (i < N) {
var aidx = alphIndex(a);
var bidx = alphIndex(b);
var aNum = parseInt(a.substr(0, aidx));
var bNum = parseInt(b.substr(0, bidx));
if (aNum < bNum) { return -1; }
if (aNum > bNum) { return 1; }
if (isNaN(aNum) && !isNaN(bNum)) { return 1; }
if (isNaN(bNum) && !isNaN(aNum)) { return -1; }
// bNum == aNum
i += aidx;
a = a.slice(aidx);
b = b.slice(bidx);
aidx = numIndex(a)
bidx = numIndex(a)
var aAlph = a.substr(0, aidx);
var bAlph = b.substr(0, bidx);
if (aAlph < bAlph) { return -1; }
if (aAlph > bAlph) { return 1; }
// bAlph == bAlph
i += aAlph.length;
a = a.slice(aidx)
b = b.slice(bidx)
}
return 0;
}
var tests = [
{
input: ['4f5', '4a', '4b'],
exp: ['4a', '4b', '4f5']
},
{
input: ['a', '5', '10a', 'b', '4f5', '4a', '4b'],
exp: ['4a', '4b', '4f5', '5', '10a', 'a', 'b']
},
{
input: [5, 3, '10a', 'b', '4f5'],
exp: [3, '4f5', 5, '10a', 'b']
},
{
input: ['bananas', 'cherries', 'apples'],
exp: ["apples", "bananas", "cherries"]
},
{
input: ["4", "3", "5", "3", "10", "11"],
exp: ["3", "3", "4", "5", "10", "11"]
},
{
input: ["1bar", "1baz", "10bar", "2baz", "10baz", "2bar", "1baz1", "1baz1foo"],
exp: ["1bar", "1baz", "1baz1", "1baz1foo", "2bar", "2baz", "10bar", "10baz"]
},
{
input: ["111aaa222bbb", "111aaa111bbb"],
exp: ["111aaa111bbb", "111aaa222bbb"]
}
];
for (var i = 0; i < tests.length; i++) {
var test = tests[i];
var got = test.input.sort(compare);
if (!equal(test.exp, got)) {
console.log("test[", i, "] ERR: \nexp", test.exp, "\ngot", got);
}
}
function equal(exp, got) {
if (exp.length !== got.length) {
return false;
}
for (var i = 0; i < exp.length; i++) {
if (exp[i] !== got[i]) {
return false;
}
}
return true;
}
</script>
</head>
<body>
<h1>sort</h1>
</body>
</html>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment