程序员成长-修炼中心 「作者:陈楚城」
导航
博客文章
  • Github (opens new window)
  • 掘金 (opens new window)
组件库 (opens new window)
关于我

chamberlain

前端持续学习者
导航
博客文章
  • Github (opens new window)
  • 掘金 (opens new window)
组件库 (opens new window)
关于我
  • 写在前面
  • vue3学习总结

  • 项目相关

  • 性能优化

  • 你不知道的css

  • 常见问题总结记录

  • 数据结构与算法

  • 设计模式

  • TS & JS进阶

  • Node

  • HTTP

  • Linux

  • 开发工具篇

  • 收藏夹

  • OS

  • Nginx

  • 项目工程化

  • 数据库

  • 计算机网络

  • 环境搭建、项目部署

  • 常用工具

  • 自动化

  • js相关

    • 函数柯里化curry
    • 继承
    • 使用setTimeout模拟setInterval
    • 手写防抖和节流
    • 手写实现拖拽
    • create
    • 手写一个call或apply
    • bind
    • 手写一个instanceOf原理
    • 手写一个JS深拷贝
    • parse和JSOn.stringify
    • 手写一个map和reduce
    • 手写一个new操作符
    • LRU缓存算法
    • 手写Promise
    • set
    • random
      • 基础版
      • 加强版
      • 进阶版
      • 最终版(Fisher–Yates)
      • 结尾
    • 原型
    • 实现Symbol类型
  • QA相关

  • 文章收藏

  • note
  • jsNote
chamberlain
2022-03-14
目录

random

# 乱序你真的会了吗?

关于乱序(数组的重新排序)你知道几种方式呢?

# 基础版

function shuffle(array) {
  array.sort(function() {
    return Math.random() - .5;
  });
}
1
2
3
4
5

可惜的是不够随机,不够乱序;看一下分布:

1621331071597_5F113761-61D6-489E-811D-58D8C2782AC1

# 加强版

function shuffle(array) {
  var n = array.length, i = -1, j;
  while (++i < n) {
    j = Math.floor(Math.random() * n);
    t = array[j];
    array[j] = array[i];
    array[i] = t;
  }
}
1
2
3
4
5
6
7
8
9

看下分布:

1621337387896_42EFE9D1-CC15-4A83-82ED-1A9FDAA9F7DD

# 进阶版

function shuffle(array) {
  var n = array.length, i = -1, j, k;
  while (++i < n) {
    j = Math.floor(Math.random() * n);
    k = Math.floor(Math.random() * n);
    t = array[j];
    array[j] = array[k];
    array[k] = t;
  }
}
1
2
3
4
5
6
7
8
9
10

看下分布:

1621337585177_9C3224F8-CFC1-49B1-BEB6-63F6341EAE38

# 最终版(Fisher–Yates)

为什么叫Fisher–Yates 呢? 因为这个算法是由 Ronald Fisher和Frank Yates首次提出的。

上代码:

function shuffle(array) {
  var m = array.length, t, i;
  while (m) {
    i = Math.floor(Math.random() * m--);
    t = array[m];
    array[m] = array[i];
    array[i] = t;
  }
}
1
2
3
4
5
6
7
8
9

看下分布:

1621337988665_58174379-CBDB-40C3-99AB-C7C808EBA296

原理很简单,就是遍历数组元素,然后将当前元素与以后随机位置的元素进行交换,从代码中也可以看出,这样乱序的就会更加彻底。

优化一下:

function shuffle(array) {
  let m = array.length, i;
  while (m) {
    i = Math.floor(Math.random() * m--);
    [array[m],array[i]] = [array[i],array[m]];
  }
}

function shuffle(array) {
  let m = array.length, i;
  while (m) {
    i = Math.floor(Math.random() * m--);
    array[m] = array[m]^array[i];
    array[i] = array[m]^array[i];
		array[m] = array[m]^array[i];
  }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17

# 结尾

你还有更好的方法吗?

更新时间: 3/15/2022, 12:28:01 AM
set
原型

← set 原型→

最近更新
01
02
网站
06-10
03
nav
06-09
更多文章>
Theme by Vdoing | Copyright © 2019-2022 chamberlain | MIT License
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式