如何让数组排序更优雅

序言

提起数组排序大家可能会觉得很简单,就是调用数组的sort就OK了, 其实真实的业务场景中排序会更加的复杂,比如说版本号排序, 姓名排序等... 今天分享一个简洁优雅的排序方式给大家, 首先大家需要知道一些前置的知识,String.localeCompareArray.sort

Array.sort

sort() 方法会对原数组的元素进行排序,并返回对相同数组的引用。默认排序是将元素转换为字符串,然后按照它们的 UTF-16 码元值升序排序。

参数

它接收一个可选参数 compareFn,同于定义排序顺序的函数。返回值应该是一个数字,其正负性表示两个元素的相对顺序。该函数使用以下参数调用:a(第一个比较元素) 以及 b(第二个比较元素)

注意, 如果省略该函数,数组元素会被转换为字符串,然后根据每个字符的 Unicode 码位值进行排序。

题外话, sort是会改变原数组的,如果你想不改变原数组排序的话, 可以使用toSorted,这个方法会返回一个新数组而不会改原数组,调用方式和 sort 是一样的。

localeCompare

相较于sort,这个api大家可能不太熟悉,这是字符串的一个api,localeCompare() 方法返回一个数字,表示参考字符串在排序顺序中是在给定字符串之前、之后还是与之相同,这个api是我们优雅实现排序的核心

参数

localeCompare() 一共有3个参数:

scss 复制代码
str1.localeCompare(str2, locales, options)
  • str1 - 要比较的第一个字符串
  • str2 - 要比较的第二个字符串
  • locales - 语言码,影响排序规则,可选
  • options - 配置对象,可包含多个选项

options 对象可以包含以下属性:

  • numeric - 是否按数字排序,默认为false
  • sensitivity - 比较字符大小写敏感度,可选值为:
    1. base(不敏感。会忽略大小写差异,'a'和'A'会被视为相等)
    2. accent (敏感度中等。会区分大小写,但会忽略某些字母变音符号的差异,比如 'e'和'é'会被视为相等)
    3. case(高度敏感。完全区分大小写,也不会忽略任何变音符号的差异。)
  • ignorePunctuation - 忽略标点符号的差异

a-z排序

了解完上述前置知识之后,我们来思考一下,如果现在有一个需求是把字符串按照 a-z 来排序,示例如下:

javascript 复制代码
const company = ['字节跳动', '网易', '拼多多', '百度', '阿里']
company.sort((a, b) => {
    // do something...
})

这里我们就要借助 localeCompare 来实现了, localeCompare 第二个参数接收一个语言码, 这里我们只需要传入中文语言码, 即可完成排序, 排序代码如下:

css 复制代码
company.sort((a, b) => a.localeCompare(b, 'zh'))

版本号排序

版本号排序其实是排序面试题中比较常见的,我们来思考一下,如果现在有一个需求是把版本号排序,示例如下:

css 复制代码
const versions = ['0.52.7.6.123', '12.5.4', '11.578.95', '0.6584.1', '0.65.83', '0.65.83.1',]
version.sort((a, b) => {})

这时候你会怎么去写这个函数呢, 一般人的思路就是把a,b两个字符串都转成数组,然后逐项比较,简洁点写出来差不多就是这样的

javascript 复制代码
versions.sort((version1, version2) => {
    const arr1 = version1.split('.').map((e) => e * 1)
    const arr2 = version2.split('.').map((e) => e * 1)
    const length = Math.max(arr1.length, arr2.length)
    for (let i = 0; i < length; i++) {
      if ((arr1[i] || 0) > (arr2[i] || 0)) return 1
      if ((arr1[i] || 0) < (arr2[i] || 0)) return -1
    }
    return 0
})

但是!上述的写法还是太繁琐了些,通过localeCompare, 其实我们一行代码就可以搞定:

css 复制代码
versions.sort((a, b) => a.localeCompare(b, undefined, { numeric: true }))

这里我们巧妙的通过配置 numerictrue来使得字符串在比较时转成数字然后去逐个比较出来最终结果用于版本号排序,实现了和上面一大串代码一样的效果。

写在结尾

平时多了解一些方法的特殊使用场景, 在真正需要用到的时候就能做到从容游刃有余。 写代码嘛, 优雅,永不过时

相关推荐
qq_4221525711 小时前
PDF 加水印工具怎么选?2026 年文档版权保护方案对比
前端·pdf·github
kyriewen11 小时前
手写 Promise.all、race、any:不到 30 行代码,解决并发异步的所有姿势
前端·javascript·面试
brucelee18612 小时前
OpenClaw 浏览器控制(Chrome MCP)完整教程
前端·chrome
ct97812 小时前
React 状态管理方案深度对比
开发语言·前端·react
胡志辉的博客12 小时前
深入浅出理解浏览器事件循环:从一道输出题讲到 Chrome 源码
前端·javascript·chrome·chromium·event loop
代码不加糖13 小时前
js中不会冒泡的事件有哪些?
前端·javascript·vue.js
懂懂tty13 小时前
Vue2与Vue3之间API差异
前端·javascript·vue.js
AI焦点13 小时前
跨越协议鸿沟:Tool Use状态机从Anthropic到OpenAI兼容体系的适配要点
前端·人工智能
Dxy123931021613 小时前
Python线程锁:为什么多线程会“打架“,以及怎么解决
开发语言·前端·python
海兰14 小时前
【web应用】Excel 项目数据自动化分析系统(AI 驱动分析)详细设计与部署指南(附源代码)
前端·人工智能·自动化·excel