如何让数组排序更优雅

序言

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

写在结尾

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

相关推荐
小飞猪Jay23 分钟前
C++面试速通宝典——13
jvm·c++·面试
_.Switch37 分钟前
Python Web 应用中的 API 网关集成与优化
开发语言·前端·后端·python·架构·log4j
一路向前的月光41 分钟前
Vue2中的监听和计算属性的区别
前端·javascript·vue.js
长路 ㅤ   41 分钟前
vite学习教程06、vite.config.js配置
前端·vite配置·端口设置·本地开发
长路 ㅤ   42 分钟前
vue-live2d看板娘集成方案设计使用教程
前端·javascript·vue.js·live2d
Fan_web1 小时前
jQuery——事件委托
开发语言·前端·javascript·css·jquery
安冬的码畜日常1 小时前
【CSS in Depth 2 精译_044】第七章 响应式设计概述
前端·css·css3·html5·响应式设计·响应式
莹雨潇潇2 小时前
Docker 快速入门(Ubuntu版)
java·前端·docker·容器
Jiaberrr2 小时前
Element UI教程:如何将Radio单选框的圆框改为方框
前端·javascript·vue.js·ui·elementui
Tiffany_Ho3 小时前
【TypeScript】知识点梳理(三)
前端·typescript