Skip to content

Instantly share code, notes, and snippets.

@Rycochet
Created May 20, 2015 14:03
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save Rycochet/dedb6b60bb023c2afd79 to your computer and use it in GitHub Desktop.
Save Rycochet/dedb6b60bb023c2afd79 to your computer and use it in GitHub Desktop.
Compare two strings accounting for multi-digit numbers
/**
* Compare two strings accounting for multi-digit numbers
* @param {(string|number)} a First string to compare
* @param {(string|number)} b Second string to compare
* @return {number} 0 if they match, -1 if a comes before b, +1 if b comes before a
*/
function strnatcasecmp(a, b) {
a = ("" + a).toLowerCase();
b = ("" + b).toLowerCase();
var a_char, a_index = 0, a_num, a_len, a_length = a.length,
b_char, b_index = 0, b_num, b_len, b_length = b.length,
isDigit = function(c) {
var charCode = c.charCodeAt(0);
return (charCode >= 48 && charCode <= 57); // 0-9
};
while (a_index < a_length && b_index < b_length) {
a_char = a.charAt(a_index++);
b_char = b.charAt(b_index++);
if (isDigit(a_char) && isDigit(b_char)) {
a_num = a_len = b_num = b_len = 0;
do {
a_len++;
a_num = a_num * 10 + parseInt(a_char, 10);
a_char = a.charAt(a_index++);
} while (isDigit(a_char));
a_index--; // Last character isn't eaten
do {
b_len++;
b_num = b_num * 10 + parseInt(b_char, 10);
b_char = b.charAt(b_index++);
} while (isDigit(b_char));
b_index--; // Last character isn't eaten
if (a_num === b_num) {
a_char = a_len;
b_char = b_len;
} else {
a_char = a_num;
b_char = b_num;
}
}
if (a_char < b_char) {
return -1;
} else if (a_char > b_char) {
return 1;
}
}
return a_length === b_length ? 0 : a_length < b_length ? -1 : 1;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment