Skip to content

Instantly share code, notes, and snippets.

@kevinw
Created December 3, 2010 19:08
Show Gist options
  • Save kevinw/727383 to your computer and use it in GitHub Desktop.
Save kevinw/727383 to your computer and use it in GitHub Desktop.
<html>
<head>
<script>
var natcompare = (function() {
var isWhitespaceChar = function(a)
{
var charCode;
charCode = a.charCodeAt(0);
if ( charCode <= 32 )
{
return true;
}
else
{
return false;
}
}
var isDigitChar = function(a)
{
var charCode;
charCode = a.charCodeAt(0);
if ( charCode >= 48 && charCode <= 57 )
{
return true;
}
else
{
return false;
}
}
var compareRight = function(a,b)
{
var bias = 0;
var ia = 0;
var ib = 0;
var ca;
var cb;
// The longest run of digits wins. That aside, the greatest
// value wins, but we can't know that it will until we've scanned
// both numbers to know that they have the same magnitude, so we
// remember it in BIAS.
for (;; ia++, ib++) {
ca = a.charAt(ia);
cb = b.charAt(ib);
if (!isDigitChar(ca)
&& !isDigitChar(cb)) {
return bias;
} else if (!isDigitChar(ca)) {
return -1;
} else if (!isDigitChar(cb)) {
return +1;
} else if (ca < cb) {
if (bias == 0) {
bias = -1;
}
} else if (ca > cb) {
if (bias == 0)
bias = +1;
} else if (ca == 0 && cb == 0) {
return bias;
}
}
}
return function (a,b) {
var ia = 0, ib = 0;
var nza = 0, nzb = 0;
var ca, cb;
var result;
while (true)
{
// only count the number of zeroes leading the last number compared
nza = nzb = 0;
ca = a.charAt(ia);
cb = b.charAt(ib);
// skip over leading spaces or zeros
while ( isWhitespaceChar( ca ) || ca =='0' ) {
if (ca == '0') {
nza++;
} else {
// only count consecutive zeroes
nza = 0;
}
ca = a.charAt(++ia);
}
while ( isWhitespaceChar( cb ) || cb == '0') {
if (cb == '0') {
nzb++;
} else {
// only count consecutive zeroes
nzb = 0;
}
cb = b.charAt(++ib);
}
// process run of digits
if (isDigitChar(ca) && isDigitChar(cb)) {
if ((result = compareRight(a.substring(ia), b.substring(ib))) != 0) {
return result;
}
}
if (ca == 0 && cb == 0) {
// The strings compare the same. Perhaps the caller
// will want to call strcmp to break the tie.
return nza - nzb;
}
if (ca < cb) {
return -1;
} else if (ca > cb) {
return +1;
}
++ia; ++ib;
}
}
}());
</script>
</head>
<body>
<script>
function updateCmp() {
setTimeout(function() {
var a = document.natcomparecheck.val1.value;
var b = document.natcomparecheck.val2.value;
var cmpresult = document.getElementById('cmpresult');
if (cmpresult)
cmpresult.innerHTML = natcompare(a, b);
}, 1);
}
</script>
<form name="natcomparecheck">
natcompare(
<input name="val1" value="10705970246197248" onchange="updateCmp()" onkeypress="updateCmp()" onkeydown="updateCmp()">
,
<input name="val2" value="9999625058521088" onchange="updateCmp()" onkeypress="updateCmp()" onkeydown="updateCmp()">
) =
<span id="cmpresult"></span>
</form>
<script>
updateCmp();
</script>
</body>
</html>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment