最近看了一篇非常有趣的文章:关于JavaScript的数组随机排序,其作者为oldj前辈。文中指出我们用来“将一个数组随机排序”的经典写法所存在的问题,获益匪浅。

本文将以更加详尽的材料和更多样的code demo进行阐述。并尝试用“Fisher–Yates shuffle”洗牌算法进行终极解答。

多个熟悉的场景

将一个数组进行乱序处理,是一个非常简单但是非常常用的需求。
比如,“猜你喜欢”、“点击换一批”、“中奖方案”等等,都可能应用到这样的处理。包括我自己在写代码的时候,也确实遇到过。
一般比较经典且流行的方案为:对对象数组采用array.sort()方法,并传入一个比较函数(comparison function),这个比较函数随机返回一个介于[-0.5, 0.5]之间的数值:

var numbers = [12,4,16,3];
numbers.sort(function() {
    return .5 - Math.random();
});

关于这么做的理论基础这里不再进行阐释。如果您不明白,可以了解一下JS中sort函数的使用方法。

有毒的array.sort方法

正像oldj前辈文章指出的那样,其实使用这个方法乱序一个数组是有问题的。

为此,我写了一个脚本进行验证。并进行了可视化处理。强烈建议读者去Github围观一下,clone下来自己试验。

脚本中,我对

var letters = ['A','B','C','D','E','F','G','H','I','J'];

letters这样一个数组使用array.sort方法进行了10000次乱序处理,并把乱序的每一次结果存储在countings当中。
结果在页面上进行输出:

var countings = [
    {A:0,B:0,C:0,D:0,E:0,F:0,G:0,H:0,I:0,J:0},
    {A:0,B:0,C:0,D:0,E:0,F:0,G:0,H:0,I:0,J:0},
    {A:0,B:0,C:0,D:0,E:0,F:0,G:0,H:0,I:0,J:0},
    {A:0,B:0,C:0,D:0,E:0,F:0,G:0,H:0,I:0,J:0},
    {A:0,B:0,C:0,D:0,E:0,F:0,G:0,H:0,I:0,J:0},
    {A:0,B:0,C:0,D:0,E:0,F:0,G:0,H:0,I:0,J:0},
    {A:0,B:0,C:0,D:0,E:0,F:0,G:0,H:0,I:0,J:0},
    {A:0,B:0,C:0,D:0,E:0,F:0,G:0,H:0,I:0,J:0},
    {A:0,B:0,C:0,D:0,E:0,F:0,G:0,H:0,I:0,J:0},
    {A:0,B:0,C:0,D:0,E:0,F:0,G:0,H:0,I:0,J:0}
];
var letters=['A','B','C','D','E','F','G','H','I','J'];
for (var i = 0; i < 10000; i++) {
    var r = ['A','B','C','D','E','F','G','H','I','J'].sort(function() {
        return .5 - Math.random();
    });
    for(var j = 0; j <= 9; j++) {
        countings[j][r[j]]++;
    }
}
for(var i = 0; i <= 9;i++) {
    for(var j = 0;j <= 

相关文章:

  • 2021-05-13
  • 2022-01-16
  • 2022-01-04
  • 2021-12-16
  • 2021-10-15
  • 2022-12-23
  • 2022-01-31
猜你喜欢
  • 2021-06-21
  • 2021-10-28
  • 2021-08-12
  • 2021-11-26
  • 2022-12-23
  • 2021-07-29
  • 2022-12-23
相关资源
相似解决方案