字符串自然排序

// html
<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=edge" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Document</title>
</head>

<body>
    <h2>字符串自然排序</h2>
    <script src="./naturalSort.js"></script>
</body>

</html>
// ts
/**
 * 找出字符中的数字
 * @param s
 * @returns result的顺序依次是 [数字前面的字符,数字,完整的字符]
 */
function naturalSortSplitor(s: string) {
  const reg = /\d+/g;
  const result = new Array<string | number>();
  let index = 0;
  for (;;) {
    const m = reg.exec(s);
    if (m) {
      if (index < m.index) {
        result.push(s.substring(index, m.index));
      }
      index = m.index + m[0].length;
      result.push(parseInt(m[0]));
    } else {
      break;
    }
  }
  result.push(s);
  return result;
}
/**
 * 字符排序:排序规则  数字 > 字符 > undefined
 * @param a
 * @param b
 * @returns
 */
function naturalSortComparator(
  a: Array<string | number>,
  b: Array<string | number>
) {
  const len = Math.max(a.length, b.length);
  for (let i = 0; i < len; i++) {
    const ai = a[i];
    const bi = b[i];
    let cp = 0;
    if (typeof ai === "string" && typeof bi === "string") {
      cp = ai.localeCompare(bi);
    } else if (typeof ai === "number" && typeof bi === "number") {
      cp = ai - bi;
    } else if (typeof ai === "number" && typeof bi === "string") {
      return -1;
    } else if (typeof ai === "string" && typeof bi === "number") {
      return 1;
    } else if (ai === undefined && bi !== undefined) {
      return 1;
    } else if (ai !== undefined && bi === undefined) {
      return -1;
    }

    if (cp !== 0) {
      return cp;
    }
  }
  return 0;
}

(function () {
  const arr = ["蓝忘机", "魏无羡", "AAA", "aaa", "157", undefined, "123"];
  console.log("排序前...", arr.concat());

  arr.sort((a, b) => {
    // 1.1 sort 的回调中参数 a 是后面一位,b 是前面一位
    console.log("后一位", a, "前一位", b);
    // 1.3 返回 1/0 代表不交换位置,-1 代表交换位置
    return naturalSortComparator(naturalSortSplitor(a), naturalSortSplitor(b));
  });
  // 1.2 sort 会自动将 undefined 排到最后,不会进回调函数
  console.log("sort 排序后...", arr);

  const arr2 = ["蓝忘机", "魏无羡", "AAA", "aaa", "157", undefined, "123"];
  for (let i = 0; i < arr2.length - 1; i++) {
    for (let j = 0; j < arr2.length - 1 - i; j++) {
      const a = arr2[j];
      const b = arr2[j + 1];
      // 2.1 模仿 sort 先传后面的数 b,再传前面的数 a,才能保证返回 -1 时需要调回位置
      //   if (
      //     naturalSortComparator(naturalSortSplitor(b), naturalSortSplitor(a)) < 0
      //   ) {
      //     const temp = arr2[j];
      //     arr2[j] = arr2[j + 1];
      //     arr2[j + 1] = temp;
      //   }
      // 2.2 如果正常顺序传入 a(前一位),b(后面一位),那么返回 -1 则代表不换位置,1/0才交换位置
      if (
        naturalSortComparator(naturalSortSplitor(a), naturalSortSplitor(b)) >= 0
      ) {
        const temp = arr2[j];
        arr2[j] = arr2[j + 1];
        arr2[j + 1] = temp;
      }
    }
  }
  console.log("冒泡排序后...", arr2);

  const arr1 = ["AAA", "aaa", "157", "123"];
  console.log("排序前...", arr1.concat());

  arr1.sort((a, b) => {
    console.log("后一位", a, "前一位", b);
    return naturalSortComparator(naturalSortSplitor(a), naturalSortSplitor(b));
  });
  console.log("排序后...", arr1);
})();

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值