如何让数组排序更优雅

序言

提起数组排序大家可能会觉得很简单,就是调用数组的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来使得字符串在比较时转成数字然后去逐个比较出来最终结果用于版本号排序,实现了和上面一大串代码一样的效果。

写在结尾

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

相关推荐
码林鼠2 小时前
2026前端面试题(二)
前端
宿6744 小时前
tsconfig.node.json
前端·javascript·vue.js
小杨互联网4 小时前
Cursor 前端 Dist 自动化逆向框架:/fr 流水线 · 4 脚本 · Vite/Webpack
前端·webpack·自动化·前端逆向框架·ai前端逆向框架
瑞码空间5 小时前
Web应用的多端部署之道:浏览器 · Electron · Docker
前端·docker·electron·浏览器·web
徐奥雯XUAOWEN5 小时前
Codex官网前端可抄吗?从技术视角深度解析与借鉴指南
前端
文艺理科生5 小时前
3 年,8 种方案,1 次重构:LangChain 记忆方案如何从混乱走向清晰
前端·后端·架构
huabuyu5 小时前
SourceMap:从「看不懂线上报错」到「让 AI 定位真根因」
前端·javascript
এ慕ོ冬℘゜5 小时前
前端树形二级列表渲染 + 页面传参完整实战解析(附原生jQuery源码)
前端·javascript·jquery
weixin_469273816 小时前
.md文件是什么?.md如何打开?
前端·编辑器
不好听6136 小时前
Web Worker:浏览器给 JS 开的后台子线程
前端·浏览器