Skip to content

Instantly share code, notes, and snippets.

@abramovantonru
Created November 8, 2016 17:58
Show Gist options
  • Save abramovantonru/95e429c41a50a3a2255afc172594dd77 to your computer and use it in GitHub Desktop.
Save abramovantonru/95e429c41a50a3a2255afc172594dd77 to your computer and use it in GitHub Desktop.
natural sort strings and numbers {js, sort, func}
function naturalSort(stringArray) {
var xor = function(a, b) {
return a ? !b : b;
};
var isDigit = function(chr) {
var charCode = function(ch) {
return ch.charCodeAt(0);
};
var code = charCode(chr);
return (code >= charCode('0')) && (code <= charCode('9'));
};
var splitString = function(str) {
var
from = 0,
index = 0,
count = 0,
splitter = {};
splitter.count = function () {
return count;
};
splitter.next = function() {
if (index === str.length) {
return null;
}
while(++index) {
var currentIsDigit = isDigit(str.charAt(index - 1));
var nextChar = str.charAt(index);
var currentIsLast = (index === str.length);
var isBorder = currentIsLast ||
xor(currentIsDigit, isDigit(nextChar));
if (isBorder) {
var part = str.slice(from, index);
from = index;
count++;
return {
IsNumber: currentIsDigit,
Value: currentIsDigit ? Number(part) : part
};
}
}
};
return splitter;
};
var compareStrings = function(str1, str2) {
var compare = function(a, b) {
return (a < b) ? -1 : (a > b) ? 1 : 0;
};
var splitter1 = splitString(str1);
var splitter2 = splitString(str2);
while (true) {
var first = splitter1.next();
var second = splitter2.next();
if (null !== first && null !== second) {
if (xor(first.IsNumber, second.IsNumber)) {
return first.IsNumber ? -1 : 1;
} else {
var comp = compare(first.Value, second.Value);
if (comp != 0) {
return comp;
}
}
} else {
return compare(splitter1.count(), splitter2.count());
}
}
};
var arr = stringArray;
return arr.sort(compareStrings);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment