Skip to content

Instantly share code, notes, and snippets.

@think49
Created March 27, 2011 08:13
Show Gist options
  • Save think49/889027 to your computer and use it in GitHub Desktop.
Save think49/889027 to your computer and use it in GitHub Desktop.
natural-language.js : 自然言語アルゴリズムで配列やノードリストをソートする
/**
* natural-language.js
* Array is sorted by natural language algorithm.
*
* @version 0.9
* @author think49
* @url https://github.com/think49
* @license http://www.opensource.org/licenses/mit-license.php (The MIT License)
* @see <a href="http://sourcefrog.net/projects/natsort/">Natural Order String Comparison</a>
*/
'use strict';
var NaturalLanguage = (function () {
'use strict';
function NaturalLanguage () {
if (!(this instanceof NaturalLanguage)) {
return new NaturalLanguage();
}
}
(function (sort, slice) {
/**
* included is-object.js
*
* @version 1.0.2
* @author think49
* @url https://gist.github.com/887049
*/
function isObject (value) {
var result;
if (value === null) {
return false;
}
switch (typeof value) {
case 'undefined':
case 'boolean':
case 'number':
case 'string':
result = false;
break;
case 'object': // Object (native and does not implement [[Call]])
case 'function': // Object (native or host and does implement [[Call]])
default: // Object (host and does not implement [[Call]])
result = true;
break;
}
return result;
}
function natCompare (string1, string2) {
var _String, _Number, result, charCode1, charCode2, isNumber1, isNumber2, isPeriod1, isPeriod2, number1, number2, numCheck, i, l;
_String = String;
string1 = _String(string1);
string2 = _String(string2);
if (string1.length > string2.length) {
l = string1.length;
result = 1;
} else if (string1.length < string2.length) {
l = string2.length;
result = -1;
} else {
l = string1.length;
result = 0;
}
string1 = string1.replace(/\s+/g, '').toLowerCase();
string2 = string2.replace(/\s+/g, '').toLowerCase();
if (string1 === string2) {
return 0;
}
_Number = Number;
number1 = '';
number2 = '';
for (i = 0; i < l; i++) {
charCode1 = string1.charCodeAt(i);
charCode2 = string2.charCodeAt(i);
isNumber1 = charCode1 > 47 && charCode1 < 58;
isNumber2 = charCode2 > 47 && charCode2 < 58;
isPeriod1 = charCode1 === 46 && number1.indexOf('.') === -1;
isPeriod2 = charCode2 === 46 && number2.indexOf('.') === -1;
if (numCheck && (isNumber1 || isNumber2 || isPeriod1 || isPeriod2) || isNumber1 && isNumber2) {
if (isNumber1 || isPeriod1) {
number1 += string1.charAt(i);
}
if (isNumber2 || isPeriod2) {
number2 += string2.charAt(i);
}
numCheck = true;
} else {
if (number1.length && number2.length) {
number1 = _Number(number1);
number2 = _Number(number2);
if (number1 > number2) {
return 1;
} else if (number1 < number2) {
return -1;
}
number1 = '';
number2 = '';
numCheck = false;
}
if (charCode1 > charCode2) {
return 1;
} else if (charCode1 < charCode2) {
return -1;
}
}
}
if (number1.length && number2.length) {
number1 = _Number(number1);
number2 = _Number(number2);
if (number1 > number2) {
return 1;
} else if (number1 < number2) {
return -1;
}
}
return result;
}
function createNatCompareWithCallback (callbackfn) {
return function (value1, value2) {
return natCompare(callbackfn(value1), callbackfn(value2));
};
}
this.sortFromArray = function sortFromArray (array/*, callbackfn*/) {
if (arguments.length > 1 && typeof arguments[1] === 'function') {
return sort.call(array, createNatCompareWithCallback(arguments[1]));
}
return sort.call(array, natCompare);
};
this.sortFromNodes = function sortFromNodes (nodes, callbackfn) {
var parentNode, node1, node2, i, len, incomplete;
if (!isObject(nodes)) {
throw new TypeError(nodes + ' is not a object');
}
if (typeof callbackfn !== 'function') {
throw new TypeError(callbackfn + ' is not a function');
}
node1 = nodes[0];
if (!node1) {
return;
}
parentNode = node1.parentNode;
if (!parentNode) {
return;
}
incomplete = true;
console.log('sortFromNodes');
console.log(nodes.length);
while (incomplete) {
incomplete = false;
for (i = 1, len = nodes.length; i < len; ++i) {
node1 = nodes[i - 1];
node2 = nodes[i];
if (natCompare(callbackfn(node1), callbackfn(node2)) === 1) {
parentNode.insertBefore(node2, node1);
len = nodes.length;
incomplete = true;
}
}
}
console.log(nodes.length);
return nodes;
};
}).call(NaturalLanguage.prototype, Array.prototype.sort, Array.prototype.slice);
return NaturalLanguage;
})();
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment