玩玩Array.sort

510 阅读2分钟

前言

最近常和数组的api们打交道,像map、forEach、filter、reduce、concat这几个,基本能满足日常的开发需求。业务开发多了无聊,偶尔遇到那么一两个稍微有趣的内容,姑且记录下吧。

需求-数组排序

业务乏味,全靠BA解闷。这不,前几天BA丢来了一个排序需求,描述如下:
按原顺序(id递增)展示选项,其中选项id为4、5、6另起一行展示。

最近看题看昏头本人,自动翻译如下👇:
重排一组自然增序的数字,取几个指定数值按增序置于数组末尾。
测试用例:   输入[2,3,4,5,6,7,8] [4,5]; 输出: [2, 3, 6, 7, 8, 4, 5]

嗯嗯,简单💡。第一下想到暴力解法:filter执行twice,concat拼接两个排序数组。无需动脑不上代码🔨

sort解法

隔天看文档时,看到了关于sort方法的描述:
sort()方法也是一个高阶函数,它还可以接收一个比较函数来实现自定义的排序。

mdn文档及写法 image.png

AFD97FC6-73A1-4B5B-A140-94F3B06DE500.png

嗯,为了避免过目即忘,还是稍微练练手吧。旧物利用,这个排序需求练手刚刚好✨

思路

自定排序函数,给数组元素值设定两种权重,遇上特定值 return 1、其他值 return -1;

初次实践

[2,3,4,5,6,7,8].sort((a,b)=>[4,5].includes(a)?1:-1)
// 输出结果 [8, 7, 6, 3, 2, 4, 5]

其他值[2,3,6,7,8]逆序翻车了;
再加筛选条件:[4,5].includes(b)?-1:1
整理一下:

[2,3,4,5,6,7,8].sort((a,b)=>[4,5].includes(a)||![4,5].includes(b)?1:-1)
// 输出结果 [2, 3, 6, 7, 8, 4, 5]

嗯!舒服!

进阶

写着写着突然好奇,乱序情况怎么处理呢?比如输入为[1,2,21,13,4,5,6,7,8,9,10,11,12]

🤔好像也不是很难,sort参数a,b均不为[4,5]的时候,递增排序就ok了。

先行判断条件改为:![4,5].includes(a)&&![4,5].includes(b)
交换结果计算为:(a-b)

整合代码如下:

[1,2,21,13,4,5,6,7,8,9,10,11,12].sort((a,b)=>![4,5].includes(a)&&![4,5].includes(b)?(a-b):[4,5].includes(a)||![4,5].includes(b)?1:-1)
// 输出结果 [1, 2, 6, 7, 8, 9, 10, 11, 12, 13, 21, 4, 5]

匆匆扫个尾

学习过程中还了解到,sort采用两种排序算法,数组元素个数<10采用二分插入排序,否则快排。

还有个难点是看sort自定义排序的入参,很难理解a是谁,b是谁。这个估计得联合排序方法另写一篇文章✏️