迹忆客 专注技术分享

当前位置:主页 > 学无止境 > WEB前端 > JavaScript >

如何在 JavaScript 中对一个数组进行随机化或洗牌

作者:迹忆客 最近更新:2023/03/10 浏览次数:

在本篇文章中,我们将学习如何在 JavaScript 中对一个数组进行洗牌或随机化处理;在 JavaScript 中洗牌数组的方法有很多,不管是通过实现洗牌算法还是使用一些库中已有的洗牌函数。

洗牌数组就是将其元素随机排列,所以主要看你如何对数组进行一定程度的重新排序或分类。

让我们继续前进,发现随机化或洗牌一个数组的不同方法。

让我们先实现一个简单的数组洗牌算法,使用 array.sort() 对数组进行排序,但使用 Math.random()-0.5 等式产生的一些随机性,-0.5 确保每次调用算法时,随机值可以是正值或负值。

让我们借助 JavaScript 引擎的力量实现这个简单的算法,并使用 Console.log() 将洗牌后的 Array 打印到控制台。

function shuffleArray(inputArray){
    inputArray.sort(()=> Math.random() - 0.5);
}

var demoArray = [1, 3, 5];
shuffleArray(demoArray);
console.log(demoArray);

输出:

[1, 5, 3]

可以计算出该数组的排列概率,以检查我们实现的算法有多优秀、多随机。

我们来看看如何衡量它的随机性。

这个简单的测量算法可以像下面这样实现。

function shuffleArray(inputArray){
    inputArray.sort(()=> Math.random() - 0.5);
}

//counts of the appearances for all possible permutations
var countDic =  {
    '153': 0,
    '135': 0,
    '315': 0,
    '351': 0,
    '531': 0,
    '513': 0,  
};

//Creating the loop
for( var i = 0; i<1000000; i++){
    var arr = [ 1 , 5 , 3];
    shuffleArray(arr);
    countDic[arr.join('')]++;
}

//Print the counts of all possible permutations
for(var key in countDic){
    console.log(`${key}: ${countDic[key]}`);
}

输出:

135: 62256
153: 375832
315: 62976
351: 311865
513: 124518
531: 62553

从上面的输出中,我们可以清楚地看到偏差,因为 135315531 出现的次数比其他的少得多,所以彼此之间的计数相似。

这种基于 JavaScript 引擎的简单算法在过去的部分中是不可靠的,但是一个叫做 Fisher-Yates 的伟大算法就其效率和可靠性而言是更好的。

Fisher-Yates 算法背后的思想是以相反的顺序走到数组,并将每个元素与前面的随机元素交换。Fisher-Yates 是一个简单但非常有效和快速的算法。

让我们来实现 Fisher-Yates 算法。

function fisherYatesShuffle(arr){
    for(var i =arr.length-1 ; i>0 ;i--){
        var j = Math.floor( Math.random() * (i + 1) ); //random index
        [arr[i],arr[j]]=[arr[j],arr[i]]; // swap
    }
}

var tmpArray = [1, 3, 5];
fisherYatesShuffle(tmpArray);
console.log(tmpArray);

我们来一步步解释一下吧

输出:

(3) [3, 1, 5]

现在让我们用之前的方法测试 Fisher -Yates

//counts of the appearances for all possible permutations
var countDic =  {
    '153': 0,
    '135': 0,
    '315': 0,
    '351': 0,
    '531': 0,
    '513': 0,  
};

//Creating the loop
for( var i = 0; i<1000000; i++){
    var arr = [ 1 , 5 , 3];
    fisherYatesShuffle(arr);
    countDic[arr.join('')]++;
}

//Print the counts of all possible permutations
for(var key in countDic){
    console.log(`${key}: ${countDic[key]}`);
}

输出:

135: 166734
153: 166578
315: 166908
351: 166832
513: 166535
531: 166413

从上面的输出,你可以看到 Fisher-Yates 算法和我们之前实现的简单算法之间的巨大差异,以及 Fisher-Yates 算法的可靠性。

著名的 Underscore.js 库也提供了一个 shuffle 函数,可以直接随机化一个数组,而不需要你写任何算法的实现。

下面我们来看一下 _.shuffle() 方法的使用实例。

首先,我们需要在 HTML 模板里面使用 Cloudflare CDN 导入这个库。

<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.15/lodash.min.js"></script>

然后我们使用 _.shuffle() 方法,如。

var tmpUnderscoreArray = [1, 3, 5];
resultArray = _.shuffle(tmpUnderscoreArray);
console.log(resultArray);

输出:

(3) [1, 5, 3]

转载请发邮件至 1244347461@qq.com 进行申请,经作者同意之后,转载请以链接形式注明出处

本文地址:

相关文章

Do you understand JavaScript closures?

发布时间:2025/02/21 浏览次数:108 分类:JavaScript

The function of a closure can be inferred from its name, suggesting that it is related to the concept of scope. A closure itself is a core concept in JavaScript, and being a core concept, it is naturally also a difficult one.

Do you know about the hidden traps in variables in JavaScript?

发布时间:2025/02/21 浏览次数:178 分类:JavaScript

Whether you're just starting to learn JavaScript or have been using it for a long time, I believe you'll encounter some traps related to JavaScript variable scope. The goal is to identify these traps before you fall into them, in order to av

How much do you know about the Prototype Chain?

发布时间:2025/02/21 浏览次数:150 分类:JavaScript

The prototype chain can be considered one of the core features of JavaScript, and certainly one of its more challenging aspects. If you've learned other object-oriented programming languages, you may find it somewhat confusing when you start

用 jQuery 检查复选框是否被选中

发布时间:2024/03/24 浏览次数:102 分类:JavaScript

在本教程中学习 jQuery 检查复选框是否被选中的所有很酷的方法。我们展示了使用直接 DOM 操作、提取 JavaScript 属性的 jQuery 方法以及使用 jQuery 选择器的不同方法。你还将找到许多有用的

扫一扫阅读全部技术教程

社交账号
  • https://www.github.com/onmpw
  • qq:1244347461

最新推荐

教程更新

热门标签

扫码一下
查看教程更方便