nameOrder.js 6.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187
  1. /**
  2. * 比较字符串
  3. * @param str1
  4. * @param str2
  5. */
  6. function strCompare(str1, str2) {
  7. // 处理数据为null的情况
  8. if (str1 == undefined && str2 == undefined) {
  9. return 0;
  10. }
  11. if (str1 == undefined) {
  12. return -1;
  13. }
  14. if (str2 == undefined) {
  15. return 1;
  16. }
  17. // 比较字符串中的每个字符
  18. let c1;
  19. let c2;
  20. let regexArr = ['-', '_', '—', '~', '·'], canRegex = /[^0-9\.]/g;
  21. // 如果都不是数字格式(含有其它内容)
  22. if (canRegex.test(str1) && canRegex.test(str2)) {
  23. for (let i = 0; i < regexArr.length; i++) {
  24. let regex = eval('(/[^0-9\\' + regexArr[i] + '\\.]/g)');
  25. // 去除后缀
  26. let tps1 = str1.replace(/\.[0-9a-zA-Z]+$/, '');
  27. let tps2 = str2.replace(/\.[0-9a-zA-Z]+$/, '');
  28. // 如果在名字正则要求范围内(没有正则以外的值)
  29. if (!regex.test(tps1) && !regex.test(tps2)) {
  30. // 转换为字符串数组
  31. let numberArray1 = tps1.split(regexArr[i]);
  32. let numberArray2 = tps2.split(regexArr[i]);
  33. return compareNumberArray(numberArray1, numberArray2);
  34. }
  35. }
  36. }
  37. // 逐字比较返回结果
  38. for (let i = 0; i < str1.length; i++) {
  39. c1 = str1[i];
  40. if (i > str2.length - 1) { // 如果在该字符前,两个串都一样,str2更短,则str1较大
  41. return 1;
  42. }
  43. c2 = str2[i];
  44. // 如果都是数字的话,则需要考虑多位数的情况,取出完整的数字字符串,转化为数字再进行比较
  45. if (isNumber(c1) && isNumber(c2)) {
  46. let numStr1 = "";
  47. let numStr2 = "";
  48. // 获取数字部分字符串
  49. for (let j = i; j < str1.length; j++) {
  50. c1 = str1[j];
  51. if (!isNumber(c1) && c1 !== '.') { // 不是数字则直接退出循环
  52. break;
  53. }
  54. numStr1 += c1;
  55. }
  56. for (let j = i; j < str2.length; j++) {
  57. c2 = str2[j];
  58. if (!isNumber(c2) && c2 !== '.') {
  59. break;
  60. }
  61. numStr2 += c2;
  62. }
  63. // 将带小数点的数字转换为数字字符串数组
  64. let numberArray1 = numStr1.split('.');
  65. let numberArray2 = numStr2.split('.');
  66. return compareNumberArray(numberArray1, numberArray2);
  67. }
  68. // 不是数字的比较方式
  69. if (c1 != c2) {
  70. return c1 - c2;
  71. }
  72. }
  73. return 0;
  74. }
  75. /**
  76. * 判断是否为数字
  77. * @param obj
  78. * @returns
  79. */
  80. function isNumber(obj) {
  81. if (parseFloat(obj).toString() == "NaN") {
  82. return false;
  83. }
  84. return true;
  85. }
  86. /**
  87. * 比较两个数字数组
  88. *
  89. * @param numberArray1
  90. * @param numberArray2
  91. */
  92. export function compareNumberArray(numberArray1, numberArray2) {
  93. for (let i = 0; i < numberArray1.length; i++) {
  94. if (numberArray2.length < i + 1) { // 此时数字数组2比1短,直接返回
  95. return 1;
  96. }
  97. let compareResult = parseInt(numberArray1[i]) - parseInt(numberArray2[i]);
  98. if (compareResult !== 0) {
  99. return compareResult;
  100. }
  101. }
  102. // 说明数组1比数组2短,返回小于
  103. return -1;
  104. }
  105. /**
  106. * 自然排序
  107. * ["第1集","第10集","第20集","第2集","1","2","10","12","23","01","02"].sort(naturalSort())
  108. * @param options { direction: 'desc', caseSensitive: true }
  109. */
  110. export function naturalSort(options) {
  111. if (!options) options = {};
  112. return function (a, b) {
  113. var EQUAL = 0;
  114. var GREATER = (options.direction == 'desc' ?
  115. -1 :
  116. 1
  117. );
  118. var SMALLER = -GREATER;
  119. var re = /(^-?[0-9]+(\.?[0-9]*)[df]?e?[0-9]?$|^0x[0-9a-f]+$|[0-9]+)/gi;
  120. var sre = /(^[ ]*|[ ]*$)/g;
  121. var dre = /(^([\w ]+,?[\w ]+)?[\w ]+,?[\w ]+\d+:\d+(:\d+)?[\w ]?|^\d{1,4}[\/\-]\d{1,4}[\/\-]\d{1,4}|^\w+, \w+ \d+, \d{4})/;
  122. var hre = /^0x[0-9a-f]+$/i;
  123. var ore = /^0/;
  124. var normalize = function normalize(value) {
  125. var string = '' + value;
  126. return (options.caseSensitive ?
  127. string :
  128. string.toLowerCase()
  129. );
  130. };
  131. // Normalize values to strings
  132. var x = normalize(a).replace(sre, '') || '';
  133. var y = normalize(b).replace(sre, '') || '';
  134. // chunk/tokenize
  135. var xN = x.replace(re, '\0$1\0').replace(/\0$/, '').replace(/^\0/, '').split('\0');
  136. var yN = y.replace(re, '\0$1\0').replace(/\0$/, '').replace(/^\0/, '').split('\0');
  137. // Return immediately if at least one of the values is empty.
  138. if (!x && !y) return EQUAL;
  139. if (!x && y) return GREATER;
  140. if (x && !y) return SMALLER;
  141. // numeric, hex or date detection
  142. var xD = parseInt(x.match(hre)) || (xN.length != 1 && x.match(dre) && Date.parse(x));
  143. var yD = parseInt(y.match(hre)) || xD && y.match(dre) && Date.parse(y) || null;
  144. var oFxNcL, oFyNcL;
  145. // first try and sort Hex codes or Dates
  146. if (yD) {
  147. if (xD < yD) return SMALLER;
  148. else if (xD > yD) return GREATER;
  149. }
  150. // natural sorting through split numeric strings and default strings
  151. for (var cLoc = 0, numS = Math.max(xN.length, yN.length); cLoc < numS; cLoc++) {
  152. // find floats not starting with '0', string or 0 if not defined (Clint Priest)
  153. oFxNcL = !(xN[cLoc] || '').match(ore) && parseFloat(xN[cLoc]) || xN[cLoc] || 0;
  154. oFyNcL = !(yN[cLoc] || '').match(ore) && parseFloat(yN[cLoc]) || yN[cLoc] || 0;
  155. // handle numeric vs string comparison - number < string - (Kyle Adams)
  156. if (isNaN(oFxNcL) !== isNaN(oFyNcL)) return (isNaN(oFxNcL)) ? GREATER : SMALLER;
  157. // rely on string comparison if different types - i.e. '02' < 2 != '02' < '2'
  158. else if (typeof oFxNcL !== typeof oFyNcL) {
  159. oFxNcL += '';
  160. oFyNcL += '';
  161. }
  162. if (oFxNcL < oFyNcL) return SMALLER;
  163. if (oFxNcL > oFyNcL) return GREATER;
  164. }
  165. return EQUAL;
  166. };
  167. }