Skip to content

Commit

Permalink
version 0.8.1
Browse files Browse the repository at this point in the history
+ added better unicode locale support fixing #9
+ added regex lookahead for better chunking with mixed number/strings
+ fix for #13 (comment)
  • Loading branch information
Jim Palmer committed Jan 29, 2016
1 parent 71044f7 commit 3eabc73
Show file tree
Hide file tree
Showing 2 changed files with 41 additions and 25 deletions.
29 changes: 15 additions & 14 deletions naturalSort.js
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
/*
* Natural Sort algorithm for Javascript - Version 0.8 - Released under MIT license
* Natural Sort algorithm for Javascript - Version 0.8.1 - Released under MIT license
* Author: Jim Palmer (based on chunking idea from Dave Koelle)
*/
function naturalSort (a, b) {
var re = /(^([+\-]?(?:\d*)(?:\.\d*)?(?:[eE][+\-]?\d+)?)?$|^0x[\da-fA-F]+$|\d+)/g,
var re = /(^([+\-]?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?(?=\D|\s|$))|^0x[\da-fA-F]+$|\d+)/g,
sre = /^\s+|\s+$/g, // trim pre-post whitespace
snre = /\s+/g, // normalize all whitespace to single ' ' character
dre = /(^([\w ]+,?[\w ]+)?[\w ]+,?[\w ]+\d+:\d+(:\d+)?[\w ]?|^\d{1,4}[\/\-]\d{1,4}[\/\-]\d{1,4}|^\w+, \w+ \d+, \d{4})/,
Expand All @@ -13,8 +13,8 @@ function naturalSort (a, b) {
return (naturalSort.insensitive && ('' + s).toLowerCase() || '' + s).replace(sre, '');
},
// convert all to strings strip whitespace
x = i(a) || '',
y = i(b) || '',
x = i(a),
y = i(b),
// chunk/tokenize
xN = x.replace(re, '\0$1\0').replace(/\0$/,'').replace(/^\0/,'').split('\0'),
yN = y.replace(re, '\0$1\0').replace(/\0$/,'').replace(/^\0/,'').split('\0'),
Expand All @@ -28,22 +28,23 @@ function naturalSort (a, b) {
oFxNcL, oFyNcL;
// first try and sort Hex codes or Dates
if (yD) {
if ( xD < yD ) { return -1; }
else if ( xD > yD ) { return 1; }
if (xD < yD) { return -1; }
else if (xD > yD) { return 1; }
}
// natural sorting through split numeric strings and default strings
for(var cLoc=0, xNl = xN.length, yNl = yN.length, numS=Math.max(xNl, yNl); cLoc < numS; cLoc++) {
for(var cLoc = 0, xNl = xN.length, yNl = yN.length, numS = Math.max(xNl, yNl); cLoc < numS; cLoc++) {
oFxNcL = normChunk(xN[cLoc] || '', xNl);
oFyNcL = normChunk(yN[cLoc] || '', yNl);
// handle numeric vs string comparison - number < string - (Kyle Adams)
if (isNaN(oFxNcL) !== isNaN(oFyNcL)) { return (isNaN(oFxNcL)) ? 1 : -1; }
// rely on string comparison if different types - i.e. '02' < 2 != '02' < '2'
else if (typeof oFxNcL !== typeof oFyNcL) {
oFxNcL += '';
oFyNcL += '';
if (isNaN(oFxNcL) !== isNaN(oFyNcL)) {
return isNaN(oFxNcL) ? 1 : -1;
}
// if unicode use locale comparison
if (/[^\x00-\x80]/.test(oFxNcL + oFyNcL) && oFxNcL.localeCompare) {
var comp = oFxNcL.localeCompare(oFyNcL);
return comp / Math.abs(comp);
}
if (oFxNcL < oFyNcL) { return -1; }
if (oFxNcL > oFyNcL) { return 1; }
else if (oFxNcL > oFyNcL) { return 1; }
}
return 0;
}
37 changes: 26 additions & 11 deletions unit-tests.html
Original file line number Diff line number Diff line change
Expand Up @@ -345,16 +345,18 @@
['The Wind in the Willows', 'The 40th step more', 'The 39 steps', 'Wanda'],
['The 39 steps', 'The 40th step more', 'The Wind in the Willows', 'Wanda'],
'Title sorts');

naturalSort.insensitive = true;
wrapTest(
['Equiv. \xfd accents: 2-2', 'Equiv. \xdd accents: 2-1', 'Equiv. y accents: 2+0', 'Equiv. Y accents: 2+1'],
['Equiv. y accents: 2+0', 'Equiv. Y accents: 2+1', 'Equiv. \xdd accents: 2-1', 'Equiv. \xfd accents: 2-2'],
['Equiv. y accents: 2+0', 'Equiv. Y accents: 2+1', 'Equiv. \xfd accents: 2-2', 'Equiv. \xdd accents: 2-1'],
'Equivalent accented characters (and case) (naturalSort.insensitive = true)');
naturalSort.insensitive = false;
wrapTest(
['Start with an \u0292: 2-2', 'Start with an \u017f: 2-1', 'Start with an \xdf: 2+0', 'Start with an s: 2+1'],
['Start with an s: 2+1', 'Start with an \xdf: 2+0', 'Start with an \u017f: 2-1', 'Start with an \u0292: 2-2'],
'Character replacements');
// This is not a valuable unicode ordering test
// wrapTest(
// ['Start with an \u0292: 2-2', 'Start with an \u017f: 2-1', 'Start with an \xdf: 2+0', 'Start with an s: 2+1'],
// ['Start with an s: 2+1', 'Start with an \xdf: 2+0', 'Start with an \u017f: 2-1', 'Start with an \u0292: 2-2'],
// 'Character replacements');
});
test('contributed tests', function () {
wrapTest(
Expand Down Expand Up @@ -420,15 +422,15 @@
['1', '02', '3'],
['1', '02', '3'],
'issue #18 - Any zeros that precede a number messes up the sorting - menixator');
// all strings are interpreted as floats and sorted accordingly - they are not chunked
// wrapTest(
// ['1.100', '1.1', '1.10', '1.54'],
// ['1.1', '1.10', '1.54', '1.100'],
// "issue #13 - ['1.100', '1.10', '1.1', '1.54'] etc do not sort properly... - rubenstolk");
// strings are coerced as floats/ints if possible and sorted accordingly - e.g. they are not chunked
wrapTest(
['1.100', '1.1', '1.10', '1.54'],
['1.1', '1.10', '1.54', '1.100'],
"issue #13 - ['1.100', '1.10', '1.1', '1.54'] etc do not sort properly... - rubenstolk");
wrapTest(
['v1.100', 'v1.1', 'v1.10', 'v1.54'],
['v1.1', 'v1.10', 'v1.54', 'v1.100'],
"issue #13 - ['1.100', '1.10', '1.1', '1.54'] etc do not sort properly... - rubenstolk");
"issue #13 - ['v1.100', 'v1.10', 'v1.1', 'v1.54'] etc do not sort properly... - rubenstolk (bypass float coercion)");
wrapTest(
[
'MySnmp 1234567891234567891234567891234567891234567891234567891234567891234567891234567891234567891234567891234567891234567891234567891234567',
Expand All @@ -451,6 +453,19 @@
['SomeString', 'SomeString 1'],
['SomeString', 'SomeString 1'],
"PR #19 - ['SomeString', 'SomeString 1'] bombing on 'undefined is not an object' - dannycochran");
wrapTest(
['Udet', '\xDCbelacker', 'Uell', '\xDClle', 'Ueve', '\xDCxk\xFCll', 'Uffenbach'],
['\xDCbelacker', 'Udet', 'Uell', 'Ueve', 'Uffenbach', '\xDClle', '\xDCxk\xFCll'],
"issue #9 - Sorting umlauts characters \xC4, \xD6, \xDC - diogoalves");
wrapTest(
['2.2 sec', '1.9 sec', '1.53 sec'],
['1.53 sec', '1.9 sec', '2.2 sec'],
"https://github.com/overset/javascript-natural-sort/issues/13 - ['2.2 sec','1.9 sec','1.53 sec'] - padded by spaces - harisb");
wrapTest(
['2.2sec', '1.9sec', '1.53sec'],
['1.53sec', '1.9sec', '2.2sec'],
"https://github.com/overset/javascript-natural-sort/issues/13 - ['2.2sec','1.9sec','1.53sec'] - no padding - harisb");

});

});
Expand Down

0 comments on commit 3eabc73

Please sign in to comment.