# sorting数组元素（带数字的string），自然sorting

``["IL0 Foo", "PI0 Bar", "IL10 Baz", "IL3 Bob says hello"]` `

` `["IL0 Foo", "IL3 Bob says hello", "IL10 Baz", "PI0 Bar"]` `

` `function compare(a,b) { if (a < b) return -1; if (a > b) return 1; return 0; }` `

` `["IL0 Foo", "IL10 Baz", "IL3 Bob says hello", "PI0 Bar"]` `

` `function naturalCompare(a, b) { var ax = [], bx = []; a.replace(/(\d+)|(\D+)/g, function(_, \$1, \$2) { ax.push([\$1 || Infinity, \$2 || ""]) }); b.replace(/(\d+)|(\D+)/g, function(_, \$1, \$2) { bx.push([\$1 || Infinity, \$2 || ""]) }); while(ax.length && bx.length) { var an = ax.shift(); var bn = bx.shift(); var nn = (an[0] - bn[0]) || an[1].localeCompare(bn[1]); if(nn) return nn; } return ax.length - bx.length; } ///////////////////////// test = [ "img12.png", "img10.png", "img2.png", "img1.png", "img101.png", "img101a.png", "abc10.jpg", "abc10", "abc2.jpg", "20.jpg", "20", "abc", "abc2", "" ]; test.sort(naturalCompare) document.write("<pre>" + JSON.stringify(test,0,3));` `
` `var re = /([az]+)(\d+)(.+)/i; var arr = ["IL0 Foo", "PI0 Bar", "IL10 Baz", "IL3 Bob says hello"]; var order = arr.sort( function(a,b){ var ma = a.match(re), mb = b.match(re), a_str = ma[1], b_str = mb[1], a_num = parseInt(ma[2],10), b_num = parseInt(mb[2],10), a_rem = ma[3], b_rem = mb[3]; return a_str > b_str ? 1 : a_str < b_str ? -1 : a_num > b_num ? 1 : a_num < b_num ? -1 : a_rem > b_rem; });` `

` `var chunkRgx = /(_+)|([0-9]+)|([^0-9_]+)/g; function naturalCompare(a, b) { var ax = [], bx = []; a.replace(chunkRgx, function(_, \$1, \$2, \$3) { ax.push([\$1 || "0", \$2 || Infinity, \$3 || ""]) }); b.replace(chunkRgx, function(_, \$1, \$2, \$3) { bx.push([\$1 || "0", \$2 || Infinity, \$3 || ""]) }); while(ax.length && bx.length) { var an = ax.shift(); var bn = bx.shift(); var nn = an[0].localeCompare(bn[0]) || (an[1] - bn[1]) || an[2].localeCompare(bn[2]); if(nn) return nn; } return ax.length - bx.length; } ///////////////////////// test = [ "img12.png", "img10.png", "img2.png", "img1.png", "img101.png", "img101a.png", "abc10.jpg", "abc10", "abc2.jpg", "20.jpg", "20", "abc", "abc2", "_abc", "_ab_c", "_ab__c", "_abc_d", "ab_", "abc_", "_ab_cd", "" ]; test.sort(naturalCompare) document.write("<pre>" + JSON.stringify(test,0,3));` `

` `var naturalSort = function (a, b) { a = ('' + a).replace(/(\d+)/g, function (n) { return ('0000' + n).slice(-5) }); b = ('' + b).replace(/(\d+)/g, function (n) { return ('0000' + n).slice(-5) }); return a.localeCompare(b); } var naturalSortModern = function (a, b) { return ('' + a).localeCompare(('' + b), 'en', { numeric: true }); } console.dir((["IL0 Foo", "PI0 Bar", "IL10 Baz", "IL3 Bob says hello"].sort(naturalSort))); console.dir((["IL0 Foo", "PI0 Bar", "IL10 Baz", "IL3 Bob says hello"].sort(naturalSortModern)));` `

` `var s = "foo124bar23"; s.match(/[^\d]+|\d+/g)` `

` `var ary = ["IL0 Foo", "PI0 Bar", "IL10 Hello", "IL10 Baz", "IL3 Bob says hello"]; // break out the three components in to an array // "IL10 Bar" => ['IL', 10, 'Bar'] function getParts(i){ i = i || ''; var parts = i.match(/^([az]+)([0-9]+)(\s.*)\$/i); if (parts){ return [ parts[1], parseInt(parts[2], 10), parts[3] ]; } return []; // erroneous } ary.sort(function(a,b){ // grab the parts var _a = getParts(a), _b = getParts(b); // trouble parsing (both fail = no shift, otherwise // move the troubles element to end of the array) if(_a.length == 0 && _b.length == 0) return 0; if(_a.length == 0) return -1; if(_b.length == 0) return 1; // Compare letter portion if (_a[0] < _b[0]) return -1; if (_a[0] > _b[0]) return 1; // letters are equal, continue... // compare number portion if (_a[1] < _b[1]) return -1; if (_a[1] > _b[1]) return 1; // numbers are equal, continue... // compare remaining string if (_a[2] < _b[2]) return -1; if (_a[2] > _b[2]) return 1; // strings are equal, continue... // exact match return 0; });` `

jsfiddle的例子

` `var arr = ["IL0 Foo", "IL10 Baz", "IL3 Bob says hello", "PI0 Bar"]; arr.sort(function (a1, b1) { var a = parseInt(a1.match(/\d+/g)[0], 10), b = parseInt(b1.match(/\d+/g)[0], 10), letterA = a1.charCodeAt(0), letterB = b1.charCodeAt(0), letterA1 = a1.charCodeAt(1), letterB1 = b1.charCodeAt(1); if (letterA > letterB) { return 1; } else if (letterB > letterA) { return -1; } else { if (letterA1 > letterB1) { return 1; } else if (letterB1 > letterA1) { return -1; } if (a < b) return -1; if (a > b) return 1; return 0; } });` `

string中的哪些差异应导致非零结果值。 可能的值是：

• `"base"` ：只有基数不同的string比较不等。 例子： `a ≠ b``a = á``a = A`
• `"accent"` ：只有在基本字母或重音和其他变音标记上有所不同的string才会被比较为不相等。 例子： `a ≠ b``a ≠ á``a = A`
• `"case"` ：只有基数不同的string或大小写比较不等的string。 例子： `a ≠ b``a = á``a ≠ A`
• `"variant"` ：基本字母，重音和其他变音标记不同的string，或情况比较不等的string。 其他差异也可能被考虑在内。 例子： `a ≠ b``a ≠ á``a ≠ A`

“sort”的使用默认是“variant”; 它的语言环境依赖于使用“search”。

` `var array = ["IL0 Foo", "PI0 Bar", "IL10 Baz", "IL3 Bob says hello"]; array.sort(function (a,b) { return a.localeCompare(b, undefined, { numeric: true, sensitivity: 'base' }); }); console.log(array);` `