数组洗牌
洗牌算法:将数组内的元素随机排序
原理
循环数组,每次在数组中随机选取一个元素,将该元素与数组的最后一个元素进行位置的交换,在不借助其他变量的前提下实现数组的重新排序。
实现
function shuffle(_array){
let n = _array.length;
// 当循环至0时,退出循环
while(n){
// Math.random()*n 即可获取大于等于0且小于n的随机数
// n-- 后置递减,运行完本条语句后才会减1
const t = Math.floor( Math.random() * n-- );
// 当前随机选中的元素会依次和倒数第1、2...的元素进行位置的交换
// 使用ES6的解构赋值,交换两者的位置
[ _array[n],_array[t] ] = [ _array[t],_array[n] ];
}
return _array;
}
优化
上面的代码是对数组内的所有元素进行洗牌,当数组很大,需要获取的随机数又很少的时候(例如抽奖),可以只进行部分洗牌,通过修改while条件来实现。
// _num:需要获取的随机元素个数
function shuffle(_array,_num){
const ns = _array.length;
let n = _array.length;
while( ns - n<_num ){
const t = Math.floor( Math.random() * n-- );
[ _array[n],_array[t] ] = [ _array[t],_array[n] ];
}
// 只返回指定数量的随机元素
return _array.slice(-_num);
}
如果需要多次调用shuffle函数,且每次返回不得重复,可以将slice()替换为splice()。