Last active
August 29, 2015 14:15
-
-
Save simonklee/537d724734b43d84b14a to your computer and use it in GitHub Desktop.
sort
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<!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