You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

JavaScript如何对字母数字混合数组先按文本后按数值排序

问题描述

现有如下字母数字混合数组:

["1","0K","11",1,"KE","PQ",5,"5"]

需要实现先按文本类型排序、后按内容规则排序的效果:纯字母开头的内容排在最前,其次是字母数字混合内容,最后是纯数字内容,同类型内再按自然顺序排序,最终得到如下结果:

["KE","PQ","0K","1",1,5,"5","11"]

当前使用localeCompare实现的排序效果不符合预期,现有代码如下:

function desc(a,b){
  //below is the code that needs improvement
  return b.toString().localeCompare(a, undefined, {
    numeric: true,
    sensitivity: "base",
  });
}

function sort(order) {
  return order === "desc"
    ? (a, b) => desc(a, b)
    : (a, b) => -desc(a, b);
}

function stableSort(array, cmp){
  const stabilizedThis = array.map((el, index) => [el, index]);
  stabilizedThis.sort((a, b) => {
    const order = cmp(a[0], b[0]);
    if (order !== 0) return order;
    return (a[1]) - (b[1]);
  });
  return stabilizedThis.map((el) => el[0]);
}

var arr = ["1","0K","11",1,"KE","PQ",5,"5"];
console.log(stableSort(arr, sort("asc")))

解决方案

原有逻辑没有区分内容的类型优先级,我们可以先给每个元素打分类标签,排序时先比较类型优先级,同优先级再用localeCompare做内容排序即可,只需要修改desc函数的逻辑:

function desc(a,b){
  // 统一转成字符串处理
  const strA = a.toString();
  const strB = b.toString();
  
  // 分类分级,返回值越小优先级越高
  const getTypeRank = (str) => {
    if(/^[A-Za-z]+$/.test(str)) return 1; // 纯字母类
    if(/\D/.test(str)) return 2; // 含非数字字符的混合类
    return 3; // 纯数字类
  }
  
  const rankA = getTypeRank(strA);
  const rankB = getTypeRank(strB);
  
  // 优先按类型排序
  if(rankA !== rankB) {
    return rankB - rankA;
  }
  
  // 同类型下按自然顺序排序
  return strB.localeCompare(strA, undefined, {
    numeric: true,
    sensitivity: "base",
  });
}

修改后调用stableSort(arr, sort("asc"))即可输出预期结果。

内容的提问来源于stack exchange,提问作者Nidhi Dadiya

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.01 14:24:03