我怎样才能洗牌一个数组? [英] How can I shuffle an array?

查看:51
本文介绍了我怎样才能洗牌一个数组?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想像这样在 JavaScript 中打乱一组元素:

I want to shuffle an array of elements in JavaScript like these:

[0, 3, 3] -> [3, 0, 3]
[9, 3, 6, 0, 6] -> [0, 3, 6, 9, 6]
[3, 3, 6, 0, 6] -> [0, 3, 6, 3, 6]

推荐答案

使用 Fisher–Yates shuffle 算法的现代版本:

/**
 * Shuffles array in place.
 * @param {Array} a items An array containing the items.
 */
function shuffle(a) {
    var j, x, i;
    for (i = a.length - 1; i > 0; i--) {
        j = Math.floor(Math.random() * (i + 1));
        x = a[i];
        a[i] = a[j];
        a[j] = x;
    }
    return a;
}

ES2015 (ES6) 版本

/**
 * Shuffles array in place. ES6 version
 * @param {Array} a items An array containing the items.
 */
function shuffle(a) {
    for (let i = a.length - 1; i > 0; i--) {
        const j = Math.floor(Math.random() * (i + 1));
        [a[i], a[j]] = [a[j], a[i]];
    }
    return a;
}

但是请注意,使用 解构交换变量分配导致显着的性能损失,截至 2017 年 10 月.

Note however, that swapping variables with destructuring assignment causes significant performance loss, as of October 2017.

var myArray = ['1','2','3','4','5','6','7','8','9'];
shuffle(myArray);

实现原型

使用 Object.defineProperty(取自这个 SO 答案的方法)我们也可以实现此函数作为数组的原型方法,而不会出现在诸如 for (i in arr) 之类的循环中.以下将允许您调用 arr.shuffle() 来对数组 arr 进行洗牌:

Implementing prototype

Using Object.defineProperty (method taken from this SO answer) we can also implement this function as a prototype method for arrays, without having it show up in loops such as for (i in arr). The following will allow you to call arr.shuffle() to shuffle the array arr:

Object.defineProperty(Array.prototype, 'shuffle', {
    value: function() {
        for (let i = this.length - 1; i > 0; i--) {
            const j = Math.floor(Math.random() * (i + 1));
            [this[i], this[j]] = [this[j], this[i]];
        }
        return this;
    }
});

这篇关于我怎样才能洗牌一个数组?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆