naturalCompare.js 1.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869
  1. "use strict";
  2. Object.defineProperty(exports, "__esModule", {
  3. value: true
  4. });
  5. exports.default = naturalCompare;
  6. /**
  7. * Returns a number indicating whether a reference string comes before, or after,
  8. * or is the same as the given string in natural sort order.
  9. *
  10. * See: https://en.wikipedia.org/wiki/Natural_sort_order
  11. *
  12. */
  13. function naturalCompare(aStr, bStr) {
  14. var aIdx = 0;
  15. var bIdx = 0;
  16. while (aIdx < aStr.length && bIdx < bStr.length) {
  17. var aChar = aStr.charCodeAt(aIdx);
  18. var bChar = bStr.charCodeAt(bIdx);
  19. if (isDigit(aChar) && isDigit(bChar)) {
  20. var aNum = 0;
  21. do {
  22. ++aIdx;
  23. aNum = aNum * 10 + aChar - DIGIT_0;
  24. aChar = aStr.charCodeAt(aIdx);
  25. } while (isDigit(aChar) && aNum > 0);
  26. var bNum = 0;
  27. do {
  28. ++bIdx;
  29. bNum = bNum * 10 + bChar - DIGIT_0;
  30. bChar = bStr.charCodeAt(bIdx);
  31. } while (isDigit(bChar) && bNum > 0);
  32. if (aNum < bNum) {
  33. return -1;
  34. }
  35. if (aNum > bNum) {
  36. return 1;
  37. }
  38. } else {
  39. if (aChar < bChar) {
  40. return -1;
  41. }
  42. if (aChar > bChar) {
  43. return 1;
  44. }
  45. ++aIdx;
  46. ++bIdx;
  47. }
  48. }
  49. return aStr.length - bStr.length;
  50. }
  51. var DIGIT_0 = 48;
  52. var DIGIT_9 = 57;
  53. function isDigit(code) {
  54. return !isNaN(code) && DIGIT_0 <= code && code <= DIGIT_9;
  55. }