naturalSort.js 1.5 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061
  1. var startWith = require('./startWith');
  2. var root = require('./root');
  3. var toStr = require('./toStr');
  4. exports = function(arr) {
  5. return arr.sort(naturalOrderComparator);
  6. };
  7. exports.comparator = naturalOrderComparator;
  8. function naturalOrderComparator(a, b) {
  9. a = toStr(a);
  10. b = toStr(b);
  11. if (startWith(a, '_') && !startWith(b, '_')) {
  12. return 1;
  13. }
  14. if (startWith(b, '_') && !startWith(a, '_')) {
  15. return -1;
  16. }
  17. var chunk = /^\d+|^\D+/;
  18. var chunka, chunkb, anum, bnum;
  19. while (true) {
  20. if (a) {
  21. if (!b) {
  22. return 1;
  23. }
  24. } else {
  25. if (b) {
  26. return -1;
  27. }
  28. return 0;
  29. }
  30. chunka = a.match(chunk)[0];
  31. chunkb = b.match(chunk)[0];
  32. anum = !root.isNaN(chunka);
  33. bnum = !root.isNaN(chunkb);
  34. if (anum && !bnum) {
  35. return -1;
  36. }
  37. if (bnum && !anum) {
  38. return 1;
  39. }
  40. if (anum && bnum) {
  41. var diff = chunka - chunkb;
  42. if (diff) {
  43. return diff;
  44. }
  45. if (chunka.length !== chunkb.length) {
  46. if (!+chunka && !+chunkb) {
  47. return chunka.length - chunkb.length;
  48. }
  49. return chunkb.length - chunka.length;
  50. }
  51. } else if (chunka !== chunkb) {
  52. return chunka < chunkb ? -1 : 1;
  53. }
  54. a = a.substring(chunka.length);
  55. b = b.substring(chunkb.length);
  56. }
  57. }
  58. module.exports = exports;