多内容排序(数字、文字、数字+文字、文字+数字...)

74 阅读2分钟

需求:

现在表格sorter排序没办法正常排序,遇到了 ['1号填表机','公安2','公安'];为什么排序不生效;

遇到了['公安2','公安','1','];也是排序异常;

现在修改为:遇到数字+文字,按照数字排序;遇到文字+数组,按照文字排序;遇到纯文字或者纯数字就直接排序;遇到空字符串直接默认第一个;

比如:['1号填表机','公安2','公安'] = ['1号填表机','公安2','公安']

['公安2','公安','1','] = ['’,'1','公安2','公安'];

问题原因:

默认情况下,sort方法会将元素转换为字符串,然后按照UTF-16代码单元的顺序进行排序。这意味着对于中文和数字混合的情况,排序可能不会按预期的数值或字母顺序进行,而是基于字符编码的值;

数据类型

  1. 数字(0)
  2. 文字(你好)
  3. 文字+数字(你好1)
  4. 数字+文字(1你好)
  5. 字母(A|a)
  6. 字母+数字(a1)
  7. 字母+中文(a你好)
  8. 中文+字母(你好A)
  9. 数字+字母(1A)
  10. null

解决思路:

判断当前项类型并单独编码

字符串

使用str.charCodeAt(0)进行编码

数字

使用Number(str)进行编码

组合类型

正则判断首位的类型重复执行以上两步

null

使用str.charCodeAt(0)进行编码

// 判断中文+数字混合
const orRex = /^((?:[\u3400-\u4DB5\u4E00-\u9FEA\uFA0E\uFA0F\uFA11\uFA13\uFA14\uFA1F\uFA21\uFA23\uFA24\uFA27-\uFA29]|[\uD840-\uD868\uD86A-\uD86C\uD86F-\uD872\uD874-\uD879][\uDC00-\uDFFF]|\uD869[\uDC00-\uDED6\uDF00-\uDFFF]|\uD86D[\uDC00-\uDF34\uDF40-\uDFFF]|\uD86E[\uDC00-\uDC1D\uDC20-\uDFFF]|\uD873[\uDC00-\uDEA1\uDEB0-\uDFFF]|\uD87A[\uDC00-\uDFE0])|(\d))+$/
// 判断纯数字
const numberRex = /^\d+$/
// 判断纯文字
const strRex = /^(?:[\u4e00-\u9fa5·]{2,16})$/
function getNumberData(data: string) {
  if (numberRex.test(data)) {
    return Number(data)
  } else if (strRex.test(data)) {
    return data[0].charCodeAt(0)
  } else if (orRex.test(data)) {
    if (numberRex.test(data[0])) {
      return Number(data[0])
    } else {
      return data[0].charCodeAt(0)
    }
  } else {
    return data[0].charCodeAt(0)
  }

}

// 使用方法
 sorter: (a, b) => {
      if (!a.winNo) return -1;
      if (!b.winNo) return 1;
      const aData = getNumberData(a.winNo);
      const bData = getNumberData(b.winNo);
      return aData - bData;
    }