资讯专栏INFORMATION COLUMN

js 数组随机数 数组洗牌

jay_tian / 523人阅读

摘要:首先通过数组调用是令系统随机选取大于等于且小于的伪随机值进入到函数后分别定义了变量和变量为当前数组的长度,先声明,以便在下面中使用。循环一圈后就形成了对数组的洗牌。

这次分享一个随机数组洗牌的一个算法,让你得到随机数组。

假如1个数组的值是这样的:

const arr = ["a", "b", "c", "d", "e", "f", "g"];

因为在实践操作中,在网上搜可以搜到一大堆随机的这些代码。但是实际上究竟是不是完全随机,效率和兼容性都有待测试,如果有这方面的需求 可以尝试以下的代码。具体这个代码的算法是如何得出的,是否是完全随机,可以看看下面文章。

德州扑克

如何随机化(shuffle)一个JavaScript数组?

费雪耶茨洗牌

下面是具体实现的代码

Array.prototype.shuffle = function() {
  let m = this.length, i;
  while (m) {
    i = (Math.random() * m--) >>> 0;
    [this[m], this[i]] = [this[i], this[m]]
  }
  return this;
}

上面代码对数组原型进行了扩展,加了 shuffle 方法 通过数组调用的方式完成的随机数组项的重组. 让我们来看下实现的过程。
首先通过数组调用
Math.random()是令系统随机选取大于等于 0.0 且小于 1.0 的伪随机 double 值

arr.shuffle(); 

进入到函数后 分别定义了 m 变量和 i 变量;
m为当前数组的长度, i先声明 ,以便在下面while中使用。
通过while循环进行遍历;

 i = (Math.random() * m--) >>> 0;

大家看到上面这行代码代码时可能对后面的表达式稍微有点疑惑:
Math.random()是随机选取大于等于 0.0 且小于 1.0 的伪随机 double 值 这个有点js基础的都知道
主要对于 >>> 0;会有点迷惑 那么他们是什么呢?

通过上述我们可以看到 这个 >>> 是无符号右移
但是位移0位有什么作用呢?
stackoverflow 查了一些资料 引入里面一个 高票的回答
原来移位操作符在移位操作前做了两种类似转换:

将不是number类型的数据转换为number,

将number转换为无符号的32bit数据,也就是Uint32类型。这些与移位的位数无关,移位0位主要就是用了js的内部特性做了前两种转换。

我们知道Uint32如果不能转换为Number,那就为0,如果为非整数,先转换为整数;

x >>> 0本质上就是保证x有意义(为数字类型),且为正整数,在有效的数组范围内(且在无意义的情况下缺省值为0;
知道了这些后我们就继续下面代码的分析
首先Math.random()会返回一个0到1之前的随机数 假设我们返回的是0.999... 那么我们在第一次循环的 m--后的值为6 那我们得到值就是 5.994.... 通过无符号右移 得到一个整数值为 5,也就是 i值现在是5 开始执行下列代码:

[this[m], this[i]] = [this[i], this[m]]

上面代码为es6新语法 解构赋值 ,通过上边代码 我们得到值 m 为6 i为5,上面代码实际实现了 下标为m的值和下标为i的值位置的互换。
后面依次执行进行循环...
因为每次循环i的值不断变化 所以位置的互换也在不断变化。 循环一圈后就形成了对数组的洗牌。
最后返回洗牌后的数组。

如果你遇到类似的需求,那就快拷贝代码,用一个数组尝试一下吧~☺

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/106293.html

相关文章

  • Underscore 源码(三)随机洗牌算法

    摘要:随机洗牌算法说实话,以前理解数组的排序,都是将数组按照一定的逻辑由大到小或者由小到大排序,我自己是没有碰到过随机打乱数组排序的问题。然后里用的是所谓的洗牌算法,很高效。总结又是三个知识点,分别是随机洗牌分组和函数的实现,没什么复杂的。 这是第三篇关于 Underscore 的源码解读,最近一段时间学的东西很少,自己太忙了,一方面忙着找实习,晚上回去还要写毕业论文。毕业论文真的很忧伤,因...

    silencezwm 评论0 收藏0
  • 数组随机排序:洗牌算法(Fisher–Yates shuffle)

    摘要:代码实现代码一测试用例输出其中,代码二测试用例输出其中,参考资料洗牌算法学习笔记数组随机排序洗牌算法给数组随机排序洗牌算法原理 原理及步骤 1.定义一个数组(shuffled),长度(length)是原数组(arr)长度2.取 0 到 index (初始0) 随机值 rand, shuffled[index] = shuffled[rand], shuffled[rand] = arr...

    张金宝 评论0 收藏0
  • 随机问题之洗牌算法

    摘要:百度文库洗牌算法提到一种换牌思路随机交换两个位置,共交换次,越大,越接近随机。洗牌插牌法优化版,可以用数学归纳法证明,这种洗牌是均匀的。每次生成一张最大的牌,与随机的某张牌换位子抽牌抽牌优化换牌插牌插牌优化文章转载自随机问题之洗牌算法 洗牌算法是我们常见的随机问题,在玩游戏、随机排序时经常会碰到。它可以抽象成这样一个问题。 得到一个M以内的所有自然数的随机顺序数组。 在百度搜洗牌算法,...

    instein 评论0 收藏0
  • 也谈前端面试常见问题之『数组乱序』

    摘要:看完部分的源码,首先迫不及待想跟大家分享的正是本文主题数组乱序。这是一道经典的前端面试题,给你一个数组,将其打乱,返回新的数组,即为数组乱序,也称为洗牌问题。关于数组乱序,正确的解法应该是,复杂度。 前言 终于可以开始 Collection Functions 部分了。 可能有的童鞋是第一次看楼主的系列文章,这里再做下简单的介绍。楼主在阅读 underscore.js 源码的时候,学到...

    tracy 评论0 收藏0
  • 洗牌算法

    摘要:描述拷贝数组从扫描数组,选择一个随机数新数组的新数组的新数组的原始数组重复第步,直到末尾最终的新数组就是随机的参考三种洗牌算法 洗牌算法 Fisher-Yates Shuffle Fisher–Yates 随机置乱算法,通俗说就是生成一个有限集合的随机排列。 描述: 写下从 1 到 N 的数字 取一个从 1 到剩下的数字(包括这个数字)的随机数 k 从低位开始,得到第 k 个还没有被...

    omgdog 评论0 收藏0

发表评论

0条评论

最新活动
阅读需要支付1元查看
<