naturalSort.js 1.5 KB

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