文档章节

我可能不懂Array.prototype.sort

o
 osc_w9s1w4o0
发布于 2019/04/02 13:47
字数 970
阅读 0
收藏 0

精选30+云产品,助力企业轻松上云!>>>

今天 fix 我们后台系统的一些 bug。系统是基于 beego 和模板开发的,各种前后端代码揉作一团,没有格式,没有 eslint,全局变量满天飞,连 js 代码都有后端的插值,读起来非常 酸爽

我耐着性子看了半天,陆陆续续改了几个 bug,顺便整理一下代码,总算完成的差不多了。只剩下最后一个小问题,乐观估计可以十分钟内搞定。想到这里,我不禁激动地哼起了小曲儿,马上要从酸爽的代码中抽身了。然而,十分钟过去了,半个小时过去了。。

<img width="30%" src="https://ws2.sinaimg.cn/bmiddle/9150e4e5ly1ful5zsspt4j205i05iwed.jpg" >

这事还真没那么简单,事情要从我自以为‘熟悉’的 Array.prototype.sort 这个方法说起。

根据 MDN 的文档,这个方法接收一个可选的 compareFunction。而这个 compareFunction 接收两个数组元素,并返回一个值决定这两个元素是否需要调换位置,规则如下:

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

知道这个规则之后,我们就可以愉快的对数组按自己规则来进行排序了,普通的升序或者降序自然没的说,然而我面对的是这么一个自定义规则:

有一个数组,由一位数,两位数和 3 位数构成;现在需要排序后的数组按整体从小到大排列,但是两位数的元素要放到最后。举个例子:

function compare(a,b){
 // TODO
}

let arr = [1, 8, 3, 11, 100, 15, 201]

arr.sort(compare)

arr //[1, 3, 8, 100, 201, 11, 15]

到了这里,大家可以先尝试写一下这个 compare 函数;如果能成功输出正确的结果,那么这篇文章对你也就没什么用了。在说答案之前,先说一个我之前理解存在的误区:

compare 函数接收到的两个元素在数组中的位置是不是一定 a 在前面,b 在后面?其实不是。在 compare 函数中打印出 a 和 b 就可以发现这一点。

自定义排序

知道 a 和 b 是无序的之后,我们就可以尝试写一下这个比较函数了,传入的元素可以分为以下 3 种情况:

  1. a,b 都是两位数时,按从小到大排序
  2. a,b 中有一个两位数,两位数放到后边
  3. a,b 都不是两位数,按从小到大排序

所以,代码如下:

function isdoubleDigit(num){ return num >= 10 && num <= 99 }
function compare(a, b){
    // 都是两位数
	if(isdoubleDigit(a) && isdoubleDigit(b)) {
      return a - b
    }
    
    // a是两位数,b不是,a应该被放到最后
    if(isdoubleDigit(a) && !isdoubleDigit(b)) {
      return 1
    }
    
    // b是两位数,a不是,b应该被放到最后
    if(!isdoubleDigit(a) && isdoubleDigit(b)) {
      return -1
    }
    // 都不是两位数,正常排序
    return a - b
}

这里说一下我原先理解中的第二个误区,那就是以为, compareFunction是用来交换a,b元素在数组中的位置的,像冒泡排序那样。其实这种看法是错误的,看下面的截图可以看出,compareFunction只是在决定排序后的数组中a,b的相对顺序,而不是对a,b的位置直接进行交换。 paixu.png

如MDN中所说,sort方法是用原地算法实现的,有兴趣的朋友可以去研究一下,本文完。

o
粉丝 0
博文 500
码字总数 0
作品 0
私信 提问
加载中
请先登录后再评论。
js高阶函数

高阶函数定义(至少满足下面条件之一的函数) - 《javascript 设计模式开发与实践》 1.函数作为形参传递2.函数作为返回值输出 1.函数作为形式参数传递 a.回调函数(异步回调,达到异步执行条件...

osc_keofad7g
2019/03/29
2
0
Array.prototype.sort()和Array.prototype.reverse()

Array.prototype.sort() sort()对数组元素进行排序然后返回数组,不一定是稳定的。默认排序顺序是根据字符串Unicode码点。 还可以传入一个排序算法的函数,用自定义的方式排序。 此方法会改变...

osc_2r66rowx
2018/06/20
2
0
神码,JavaScript!

在2011年的BlackHat DC 2011大会上Ryan Barnett给出了一段关于XSS的示例javascript代码: ($=[$=[]][(__=!$+$)[=-~-~-~$]+({}+$)[/]+($$=($=!''+$)[/]+$_[+$])])()[/]+[+~$]+$[_]+$$ 这是一段......

答复哈
2011/03/10
84
0
神码,JavaScript!

在2011年的BlackHat DC 2011大会上Ryan Barnett给出了一段关于XSS的示例javascript代码: 这是一段完全合法的javascript代码,效果相当于alert(1)。它可以在大部分浏览器上运行。(虽然目前我...

答复哈
2011/03/10
403
1
模拟 javaScript Array 原型上的方法

Array.prototype.push Array.prototype.pop Array.prototype.shift Array.prototype.unshift Array.prototype.slice Array.prototype.concat Array.prototype.splice Array.prototype.reduce......

_落雨_
2019/04/13
0
0

没有更多内容

加载失败,请刷新页面

加载更多

会议通知 | 2020中国计算与认知神经科学会议

关于大会关于 计算神经科学以神经生物实验为基础,以建立数学模型,开展计算模拟和分析作为基本手段,来刻画和描述大脑的神经活动,探究神经系统各种复杂活动和认知功能包括注意、学习、记忆...

脑机接口社区
06/02
17
0
大神分享快3怎么算下期和值

大神分享快3怎么算下期和值{叩67790572}使用的标签:constructor-arg标签出现的位置:bean标签的内部标签中的属性type:用于指定要注入的数据的数据类型,该数据类型也是构造函数中某个...

yiren081
18分钟前
21
0
Matlab系列之运算符和标点符号的功能介绍

本来月初就打算接着写的,但是电脑不小心进水,主板什么的都废了,周末才找时间拿去修好,心塞。 就不多讲太多废话了,开始分享今天的内容,对MATLAB的运算符做个介绍,然后再对标点符号进行...

狂人V
07/06
3
0
Java源码系列(1):Comparable和Comparator的区别

在讲Comparable和Comparator区别之前,先补充一个知识点。 先看代码: Person类 1public class Person<T> { 2  private T id; 3 4  public T getId() { 5    return i...

学习Java的小姐姐
2018/09/19
19
0
ThreadPoolTaskScheduler手写调度中心

先贴一个自己写的demo把,原理其实就是这样的。 CronTrigger这个类可以将cron表达式转换成Date,可以查看schedule源码学到不少东西,下面代码就是转换成下一执行时间。 public Date nextEx...

朝如青丝暮成雪
39分钟前
14
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部