前言

先看一个段代码

function randArr (arr) {
return arr.sort(() => {
return (Math.random() - 0.5);
});
}

目的是为了实现给定数组的乱序。

利用数组的sort方法,判断随机出来的0~1的值与0.5的大小,实现伪排序。

为什么说是伪排序呢?代码的逻辑没毛病啊。

对,从这个层面来看,简单明了,完美的实现了需求,本着凡事往祖坟刨得精神。来看看这段代码的内部实现。

浏览器实现

ECMA Script

The elements of this array are sorted. The sort is not necessarily stable (that is, elements that compare equal do not necessarily remain in their original order). If comparefn is not undefined, it should be a function that accepts two arguments x and y and returns a negative value if x < y, zero if x = y, or a positive value if x > y.

大致说的意思是,我不管你排序的算法稳不稳定,反正你能给用户自定义排序规则就行,不给你就爱咋折腾咋折腾~

这帮浏览器一听,好啊,老大发话了,那就八仙过海各显神通,各自都认为自己的实现是最牛逼的。

Chrome的sort

基于V8引擎,它的排序算进行了很多的优化,但是核心是小于等于10的数组用插入排序(稳定),大于10的采用了quickSort(不稳定),源码

FireFox的sort

基于SpiderMonkey引擎,采用了归并排序(稳定), 源码

Safari的sort

基于Nitro(JavaScriptCore )引擎,如果没有自定义的排序规则传入,采用桶排序(不一定稳定, 桶排序的稳定性取决于桶内排序的稳定性, 因此其稳定性不确定。),传入自定义规则,采用归并排序(稳定),源码

Microsoft Edge/IE9+

基于Chakra引擎,采用快排(不稳定)源码

好了,那个说sort可以不是伪排序的同学,你看见我这40米的大刀没?

什么,你还嘴硬,我喜欢你的性格,看下面:

github上的大神对  var letters = ['A','B','C','D','E',‘F’,‘G’,'H','I','J'];

进行了10000次乱序处理,发现结论: 元素大概率停留在自己的初始位置。

具体地址: HOUCe/shuffle-array

看见没,矮要承认,挨打要立正。

洗牌算法(Fisher-Yates)

想要实现真正意义上的乱序,我们来研究一下:只要满足每个元素出现在各个位置的概率同等即可。

少年,听过如来神掌吗?

有个Fisher-Yates的洗牌算法,满足您的各种乱序需求,物美价廉,杀人越货居家旅行的必备精品~(其实有三个版本,有兴趣的自行搜索)

算法的大致描述

1.找到数组的屁股(最后一个元素);

2.在脑袋和屁股中间随机一个位置;

3.交换元素;

4.这时屁股是已经乱序后的元素,所以屁股前移;

5.如果屁股没打到脑袋上就继续1~4的步骤

function shuffle(arr) {
let length = arr.length,
r = length - 1,
rand = 0; while (r) {
rand = Math.floor(Math.random() * r--);
[arr[r], arr[rand]] = [arr[rand], arr[r]];
} return arr;
}

参考文献

https://github.com/HOUCe/shuffle-array

https://en.wikipedia.org/wiki/Fisher%E2%80%93Yates_shuffle

http://efe.baidu.com/blog/talk-about-sort-in-front-end/

https://segmentfault.com/a/1190000010648740

JavaScript tips —— 谈谈数组乱序的更多相关文章

  1. JavaScript中实现最高效的数组乱序方法

    数组乱序的意思是,把数组内的所有元素排列顺序打乱. 常用的办法是给数组原生的sort方法传入一个函数,此函数随机返回1或-1,达到随机排列数组元素的目的. 复制代码代码如下: arr.sort(fun ...

  2. js数组乱序输出 数组乱序排列

    网上看的数组乱序输出,要么不合实际,要么代码繁琐.自己试了下,希望能给大家带来帮助. 重要思想也是Math.random*arr.length随机下标,然后删除取到的元素,继续随机下标. //将数组乱 ...

  3. [转载]排序:长度为n的数组乱序存放着0至n-1. 现在只能进行0与其他数的swap

    长度为n的数组乱序存放着0至n-1. 现在只能进行0与其他数的swap 请设计并实现排序. google笔试小题.题目来源:http://wenku.baidu.com/view/5aa818dda5 ...

  4. js之数组乱序

    这是最近面试遇到的,不过忘记了,之前也有印象刷到过这道题,就再次记录一下加深印象吧,听到最多的答案是利用sort方法,不过也有说这种方法不好,利用了快排和插入排序,那就整理下吧 <!DOCTYP ...

  5. 高频重要前端API手写整理(call,apply,bind,instanceof,flat,filter,new,防抖,节流,深浅拷贝,数组乱序,数组去重,继承, lazyman,jsonp的实现,函数的柯里化 )

    Function.prototype.call = function(context,...args){ var context = context || window; context.fn = t ...

  6. javascript专题系列--js乱序

    乱序的意思想必没有不知道:就是将数组打乱. 听到乱序一般都会想到js的随机函数Math.random(); var values = [1, 2, 3, 4, 5]; values.sort(func ...

  7. c#几种随机数组和数组乱序

    相关资料MSDN:RNGCryptoServiceProvider   Random   Guid private static RNGCryptoServiceProvider rngCsp = n ...

  8. javascript洗牌算法 乱序算法 面试题

    1.2种方案代码 <!DOCTYPE html> <html lang="zh"> <head> <meta charset=" ...

  9. java将一数组乱序排列

    JAVA的Collections类中shuffle方法模拟了“洗牌”动作可以对list列表进行随机排序.如果一定要自己写,算法也很简单:假设数组array长度为n.用标准随机函数rand(n)生成[0 ...

随机推荐

  1. 学习使用turtlebot2——turtlebot2上使用Hokuyo激光雷达(型号UST-10LX)

    目标     在turtlebot2上添加Hokuyo激光雷达传感器,使用激光雷达调用gmapping进行建图. 配置情况     电脑使用Ubuntu 14.04版本,ROS为 Indigo,激光雷 ...

  2. 安装Vmware ESX Server5.5 ——hardware virtualization is not a feature of the cpu or is not enabled in the BIOS

    Error信息: hardware virtualization is not a feature of the cpu or is not enabled in the BIOS 解决方案: F2进 ...

  3. JavaScript 学习(3)核心对象

    ##JavaScript 学习 3 1.核心对象 1.1 String对象 声明和生成 var myString="Hello"; var myString=new String( ...

  4. python基础之类的继承与派生、组合、接口与归一化设计、抽象类、子类中调用父类方法

    一.什么是继承 继承是一种创建新的类的方式,新建的类可以继承自一个或者多个父类,原始类称为基类或超类,新建的类称为派生类或子类. 派生:子类继承了父类的属性,然后衍生出自己新的属性,如果子类衍生出的新 ...

  5. MIS货物拆包销售的问题

    就是不能拆包装销售.比如一箱香烟要一包包的卖,一箱里面有50条,一条里面有10包,而是,要一包一包的卖. 解决方案:入库的时候,记录下包装总量(自动改成数量×50),再附加2条说明字段,第一条说明是一 ...

  6. ionic真机调试Android报错 - could not read ok from ADB Server * failed to start daemon * error: cannot connect to daemon

    在使用真机调试Android程序时,报错如下: could not read ok from ADB Server * failed to start daemon error: cannot con ...

  7. 线性表 - C语言完整实现

    #include <stdio.h> #define false 0 #define true 1 #define MAXSIZE 20 typedef int bool; typedef ...

  8. MySQL -表完整性约束(Day41)

    阅读目录 一.介绍 二.not null 与 default 三.unique 四.primary key 五.auto_increment 六.foreign key 七. 总结 一 介绍 回到顶部 ...

  9. this与super关键字总结

    Ⅰ.this 用类名定义一个变量的时候,定义的应该只是一个引用,外面可以通过这个引用来访问这个类里面的属性和方法.类里面也有一个引用来访问自己的属性和方法,这个引用就是 this 对象,它可以在类里面 ...

  10. spring和spirngmvc整合

    <!-- 需要进行 Spring 整合 SpringMVC 吗 ? 还是否需要再加入 Spring 的 IOC 容器 ? 是否需要再 web.xml 文件中配置启动 Spring IOC 容器的 ...