你知道吗?JavaScript的sort()还可以这样排序

677 阅读5分钟

前言

一、 基本排序和介绍

参数🥝🍅🥥🥑

arr.sort()不传参数 OR arr.sort(compareFunction)传参数,参数是一个比较函数

返回值🥝🍅🥥🥑

排序后的数组。请注意,数组已原地排序,并且不进行复制。

关于是否带参数的区别🥝🍅🥥🥑

如果没有指明 compareFunction ,那么元素会按照转换为的字符串的诸个字符的Unicode位点进行排序。例如 "Banana" 会被排列到 "cherry" 之前。当数字按由小到大排序时,9 出现在 80 之前,但因为(没有指明 compareFunction),比较的数字会先被转换为字符串,所以在Unicode顺序上 "80" 要比 "9" 要靠前。

1、不传参数

const array1 = [1, 30, 4, 21, 100000];
array1.sort();
console.log(array1);
// expected output: Array [1, 100000, 21, 30, 4]

image.png

2、传参数(比较函数)

arr.sort(compareFunction)传参数,参数是一个比较函数

如果指明了 compareFunction ,那么数组会按照调用该函数的返回值排序。即 a 和 b 是两个将要被比较的元素:

  • 如果 compareFunction(a, b) 小于 0 ,那么 a 会被排列到 b 之前;
  • 如果 compareFunction(a, b) 等于 0 , a 和 b 的相对位置不变。备注: ECMAScript 标准并不保证这一行为,而且也不是所有浏览器都会遵守(例如 Mozilla 在 2003 年之前的版本);
  • 如果 compareFunction(a, b) 大于 0 , b 会被排列到 a 之前。
  • compareFunction(a, b) 必须总是对相同的输入返回相同的比较结果,否则排序的结果将是不确定的。 一般的表示升序方式
arr.sort((a, b) => a - b)

一般的表示降序方式

arr.sort((a, b) => b - a)

要是没有箭头函数 ,还要写成这样

arr.sort(function compare(a, b) {
  if (a < b ) {           // 按某种排序标准进行比较, a 小于 b
    return -1;
  }
  if (a > b ) {
    return 1;
  }
  // a must be equal to b
  return 0;
})

// 简化
arr.sort(function compareNumbers(a, b) {
  return a - b;
})

用来指定按某种顺序进行排列的函数。如果省略,元素按照转换为的字符串的各个字符的Unicode位点进行排序。


const array1 = [1, 30, 4, 21, 100000];
array1.sort((a, b) => a - b);
console.log(array1);
// expected output: Array [1, 4, 21, 30, 100000]

image.png

二、 对象排序

根据数组对象的某个属性进行排序,如下以对象里年龄进行排序

let data = [
  {name:'张三', age:20, sex:'boy'},
  {name:'李四', age:18, sex:'girl'},
  {name:'王老五', age:25, sex:'boy'},
]
console.log('排序前---------------', data);
data.sort((a,b) => a.age - b.age)
console.log('排序后---------------',data);



image.png

三 、特殊需求排序

例如一个字符串类型的数组,我们要不区分大小写 ,🥝🍅🥥🥑以A-Z 这样排序, 那么很明显我们直接排序的话肯定不行,像这样直接排序的话

let list = ['Delta', 'alpha', 'CHARLIE', 'bravo'];
list.sort()

console.log(list);

下面这样,得到的排序结构显然不是我们想要的

image.png

如何优雅的解决🍑🍒🍓🥝🍅🥥🥑

我们利用arr.map(),数组映射的方式。

    • 通过map,给数组的每一项引入index属性记录当前在list数组的下标,来记录当前,对应下标,将元素先应的toLowerCase()转为小写,这些对象存储的临时数组mapped
    • 给临时数组mapped的元素进行sort排序,排序后
    • 排序后在通过下标index,map 得到目标排序结果

// 需要被排序的数组
let list = ['Delta', 'alpha', 'CHARLIE', 'bravo'];

// 对需要排序的数字和位置的临时存储
let mapped = list.map(function(el, i) {
  return { index: i, value: el.toLowerCase() };
})
console.log(mapped);
// 按照多个值排序数组
mapped.sort((a, b) => +(a.value > b.value) || +(a.value === b.value) - 1)

console.log(mapped);

// 根据索引得到排序的结果
let result = mapped.map((el) => list[el.index] )
console.log(result);

三个阶段的变化结果,最后result得到排序结果

image.png

四 、 解构排序

如何给对象排序呢?

体育课上,有一班同学,如下:

let classmates = {
  tom: 180,
  jack: 178,
  alice: 160,
  jonhy: 189,
  zanne: 178,
}

首先是转换为数组进行排序吧,吗?Object.entries(classmates)将对象转换为二维数组

let res = Object.entries(classmates)
console.log(res);

image.png

一维的正常我们指定怎么排序了,那二维数组要怎么排序呀???

其实也好办,学过ES6🍑🍒🍓🥝🍅🥥🥑的我们当然知道结构赋值咧,像这样我们,结构出来,就还是一样的操作了。

res.sort(([, a], [, b]) => a - b)


let classmates = {
  tom: 180,
  jack: 178,
  alice: 160,
  jonhy: 189,
  zanne: 178,
}
let res = Object.entries(classmates)
res.sort(([, a], [, b]) => a - b)
console.log(res);

五 、 高级解构排序

我们看看一道牛客网的一道题目

华为机试题,统计字符

image.png 下面统计字符的详细版之前面试文章有讲到。

统计字符个数详细 本题的难点是多条件排序问题,细节看注释

let str = readline() // 读取输入字符串
let obj = {} // 定义哈希对象
let res = '' 
for(let i = 0; i< str.length; i++){
    if(obj[str[i]]) obj[str[i]]++
    else obj[str[i]] = 1
}
let arr = Object.entries(obj) // 对象转为二维数组
// 多条件排序
arr.sort((a,b)=> {
    if(a[1] == b[1]) return a[0].charCodeAt() - b[0].charCodeAt() // 字符数量相同时升序SCII sxu
    else return b[1] - a[1] // 按照字符数量降序
})
// 循环拼接
for(item of arr){
    res += item[0]
}
print(res)// 返回结果,print 打印,同console.log() 

统计字符题解 上面我们用到的高级sort()操作,我们可以根据数组里边的内容进行多条件排序 排序字符串,按照个数降序,按照ASCII码由小到大排序

arr.sort((a,b)=> {
    if(a[1] == b[1]) return a[0].charCodeAt() - b[0].charCodeAt()
    else return b[1] - a[1]
})

六、总结

🍠本节介绍了数组的排序方法,sort(),他是一个原地排序的排序方法,其底层的排序算法是,十大排序算法中的稳定,快速的那个🍑🥝🍅🥥🥑【快速排序算法】。所以比较快哈哈哈。

🍇🥧🍠🥐JavaScript ES TypeScript 我们能感受到js 这家伙越来越有趣了,每年ES系列推出的新语法,以及语法糖也越来越有意思,代码规范得很优雅。

现今框架框架和插件越来越多,但是我们觉得最后浏览器只需都的都还是JavaScript, 用Typescript写的最后也是编译为JavaScript,webpack打包之后也还是JavaScript,所以原生的JavaScript我们觉得还是有必要知道。

🍑🍒🍓🥝🍅🥥🥑友情连接 点击下方

Vue3+Vite+TS基于Element plus 二次封装业务组件(含Vue3知识点)

js 数组去重十几种解法,基础知识扎实吗?(附数组方法)

如果文章对你有帮助,不妨点赞、评论、关注~

206a144160ba659e24c126ebef4c5f4d.jpg