数组洗牌

洗牌算法:将数组内的元素随机排序

原理

循环数组,每次在数组中随机选取一个元素,将该元素与数组的最后一个元素进行位置的交换,在不借助其他变量的前提下实现数组的重新排序。

实现

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()。

作者

BiteByte

发布于

2020-08-08

更新于

2024-11-15

许可协议