js数组排序规则

排序问题是比较常见的,最近的功能用到了前端的排序,当然其实大部分请求尤其是分页和配置的,都应该交给后端做排序,首先数组的排序用到了sort()函数

MDN对sort()的介绍

sort()方法用原地算法对数组的元素进行排序,并返回数组。默认排序顺序是在将元素转换为字符串,然后比较它们的UTF-16代码单元值序列时构建的

由于它取决于具体实现,因此无法保证排序的时间和空间复杂性。 

w3school对sort()的介绍

如果想按照其他标准进行排序,就需要提供比较函数,该函数要比较两个值,然后返回一个用于说明这两个值的相对顺序的数字。比较函数应该具有两个参数 a 和 b,其返回值如下:

  • 若 a 小于 b,在排序后的数组中 a 应该出现在 b 之前,则返回一个小于 0 的值。
  • 若 a 等于 b,则返回 0。
  • 若 a 大于 b,则返回一个大于 0 的值。

通过以上的信息,可以知道和map,forEach一样,sort函数接收一个回调函数作为参数,这个回调函数有两个形参,表示数组元素中的前者和后者,根据两者的差值做原地排序,废话不多说来一个最简单的demo体验一下

[1, 88, 12, 0, -10, 22].sort((a, b) => a - b)

等价于

[1, 88, 12, 0, -10, 22].sort(function(a, b){ return a - b})

 当a大于b的时候,把a放到b的前面,对整个数组做迭代操作,大白话就是对整个数组做升序排列

[-10, 0, 1, 12, 22, 88]

当然实际的开发中的数据肯定复杂得多,模拟一个需求对数组[ '标签名', '通配符', '内联', 'id', '类名' ]进行排序,对于前端来说很熟了,权重是 内联 < id < 类名 < 标签名 < 通配符,按照字符串排序肯定是行不通的,我们要把权重的排序规则具象化,最直观的方法,通过js的键值形式重新生成一套数组让每一个元素变成{value: '标签名',weight: 400 },最后对每一个元素的weight比较就行了

const rules = [
   {value: '类名', weight: 300}, 
   {value: '内联', weight: 100}, 
   {value: 'id', weight: 200},
   {value: '标签名', weight: 400}, 
   {value: '通配符', weight: 500}
]

 有了规则就好办了,每一次拿到值的时候都去rules里面去查它的权重是多少然后比较就行了

const array = [ '标签名', '通配符', '内联', 'id', '类名' ]

array.sort((a,b)=>{
    //使用数组的find函数找到a,b的权重,
    const aw = rules.find(obj => obj.value == a).weight;
    const bw = rules.find(obj => obj.value == b).weight;
    return aw - bw;
})

如果考虑配置不全的情况,同样是升序排列

array.sort((a,b)=>{
    
    const av = rules.find(obj => obj.value == a);
    const bv = rules.find(obj => obj.value == b);
    //如果没找到就给一个默认值
    let aw = 9999;
    let bw = 9999;
    if(av){ aw = av.weight; }
    if(bv){ bw = bv.weight; }

    return aw - bw;
})

有没有优化的方法呢,一提到排序我想到了数字也就是自然序列,排序的配置我可以不使用键值对象,直接用排好的数组,然后对比下标值

const rules = ['地月系', '太阳系', '银河系', '本星系群', '室女座超星系团', '宇宙视界'];
const array = [ '地月系', '本星系群', '太阳系', '银河系', '宇宙视界', '室女座超星系团'];

array.sort((a,b)=>{
    //使用indexOf函数找到a,b的下标
    const ai = rules.indexOf(a);
    const bi = rules.indexOf(b);
    return ai - bi;
})

 注意indexOf如果找不到元素会返回-1,这个默认值也需要处理成我们想要的值,重点在于排序规则的配置和空值的处理,只要理解了这个,代码的实现层面还是比较简单的,多练习一下

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

free5156

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值