如何让数组排序更优雅

序言

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

写在结尾

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

相关推荐
Bruce_Liuxiaowei21 分钟前
一键清理Chrome浏览器缓存:批处理与PowerShell双脚本实现
前端·chrome·缓存
怒放的生命199121 分钟前
Vue 2 vs Vue 3对比 编译原理不同深度解析
前端·javascript·vue.js
GDAL29 分钟前
html返回顶部实现方式对比
前端·html·返回顶部
Violet_YSWY29 分钟前
ES6 () => ({}) 语法解释
前端·ecmascript·es6
C雨后彩虹30 分钟前
字符串拼接
java·数据结构·算法·华为·面试
LYFlied32 分钟前
【每日算法】LeetCode 279. 完全平方数(动态规划)
前端·算法·leetcode·面试·动态规划
小北方城市网35 分钟前
第7课:Vue 3应用性能优化与进阶实战——让你的应用更快、更流畅
前端·javascript·vue.js·ai·性能优化·正则表达式·json
向下的大树36 分钟前
React 环境搭建 + 完整 Demo 教程
前端·react.js·前端框架
IT_陈寒1 小时前
Python性能翻倍的5个隐藏技巧:让你的代码跑得比同事快50%
前端·人工智能·后端
Можно1 小时前
GET与POST深度解析:区别、适用场景与dataType选型指南
前端·javascript