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

如何实现含隐式数字的字母数字自然排序?(JavaScript)

自然排序(人类排序)的实现

这种能识别字符串中隐式/显式数字、符合人类直觉的排序方式叫做自然排序(也常称人类排序、字母数字排序),它区别于普通字典序排序——普通排序会把"Kane & Lynch 2..."中的"2"当作字符和":"比较,而自然排序会将数字视为数值,自动识别出"Kane & Lynch: Dead Men"隐含的序号1,让它排在带2的条目之前。

在JavaScript中可以轻松实现,推荐两种方式:

1. 使用原生Intl.Collator(推荐)

ES6及以上环境支持的原生API,性能优且支持多语言,只需开启numeric参数:

const titles = [
  'Kane & Lynch 2: Dog Days',
  'Kane & Lynch: Dead Men',
  'Grand Theft Auto V',
  'Grand Theft Auto III'
];

// 初始化排序器,numeric: true开启数字数值比较
const naturalCollator = new Intl.Collator(undefined, { 
  numeric: true, 
  sensitivity: 'base' // 忽略大小写和重音,可按需调整
});

// 执行排序
titles.sort(naturalCollator.compare);

console.log(titles);
// 输出顺序:
// ["Kane & Lynch: Dead Men", "Kane & Lynch 2: Dog Days", "Grand Theft Auto III", "Grand Theft Auto V"]

2. 自定义排序函数(兼容老环境)

如果需要兼容ES6之前的环境,可以自己实现基于正则拆分的排序逻辑:

function naturalSort(a, b) {
  const numSplitRegex = /(\d+)/g;
  // 将字符串拆分为「非数字段+数字段」的数组,数字转数值,非数字转小写统一比较
  const splitA = a.split(numSplitRegex).map(segment => 
    isNaN(segment) ? segment.toLowerCase() : parseInt(segment, 10)
  );
  const splitB = b.split(numSplitRegex).map(segment => 
    isNaN(segment) ? segment.toLowerCase() : parseInt(segment, 10)
  );

  // 逐个比较拆分后的片段
  for (let i = 0; i < Math.max(splitA.length, splitB.length); i++) {
    const partA = splitA[i] ?? '';
    const partB = splitB[i] ?? '';

    if (partA !== partB) {
      // 数字比较数值大小,非数字用localeCompare做自然字符串比较
      return typeof partA === 'number' ? partA - partB : partA.localeCompare(partB);
    }
  }
  return 0;
}

// 执行排序
titles.sort(naturalSort);

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.24 04:45:44