比random更乱的洗牌算法

洗牌算法

今天在做一个随机数,感觉js里面的random函数不够随机,于是想着写一个更加松散的洗牌算法,可以用于随机播放列表随机排序列表等场景。

逻辑
  • 拿到原始数据
  • 使用for循环来处理这个数据
  • 根据for循环中的i值随机生成一个0-max的整数
  • 拿到随机生成的坐标后,当前坐标和随机生成的坐标做交换
  • 待for循环处理完成后,返回新的数据,完成洗牌

这样处理的目的就是把数组打的更乱,相当于洗牌更松散,也就达成了比random更加随机的效果。

开工

我使用的是Vue,所以还是在脚手架项目里进行操作。

新建一个公共js文件utils.js来存放封装的函数,以便于其它地方使用的时候直接调用。

  1. 首先使用slice函数初始化一个数据,source为传入的源数据。
const arr = source.slice()
  1. 构造一个生成0-max下标的函数。这个函数为生成的随机数下标做服务。
function getRandomInt (max) {
  return Math.floor(Math.random() * (max + 1))
}

这里这里的返回值为0-max的随机整数,使用floor来处理。

方法参数解读:

Math.floor() :返回小于或等于一个给定数字的最大整数,通俗易懂的说就是向下取整;

Math.random():返回一个浮点数,范围从0到1,包括0不包括1,数学理解为[0,1);

  1. 定义一个交换函数,也就是众所周知的交换排序,感觉这段代码能刻在DNA里面了。
function swap (arr, i, j) {
  const t = arr[i]
  arr[i] = arr[j]
  arr[j] = t
}
  1. 最后利用for循环来进行处理并返回新数组
for (let i = 0; i < arr.length; i++) {
  const j = getRandomInt(i)
  swap(arr, i, j)
}
return arr
全部代码
// 洗牌算法
export function shuffle(source) {
  const arr = source.slice()
  for (let i = 0; i < arr.length; i++) {
    const j = getRandomInt(i)
    swap(arr, i, j)
  }
  return arr
}

// 获取0-max之间的函数
function getRandomInt (max) {
  return Math.floor(Math.random() * (max + 1))
}

// 交换坐标
function swap (arr, i, j) {
  const t = arr[i]
  arr[i] = arr[j]
  arr[j] = t
}

你可能感兴趣的:(比random更乱的洗牌算法)