我有一个这样的数组:

var arr1 = ["a", "b", "c", "d"];

我如何随机化/打乱它?


当前回答

$=(m)=>控制台日志(m);//----将此方法添加到Array类Array.prototype.shuffle=函数(){return this.sort(()=>.5-Math.random());};$([1,65,87,45101,33,9].shuffle());$([1,65,87,45101,33,9].shuffle());$([1,65,87,45101,33,9].shuffle());$([1,65,87,45101,33,9].shuffle());$([1,65,87,45101,33,9].shuffle());

其他回答

使用underscore.js库。对于这种情况,方法_.shuffle()很好。以下是该方法的示例:

var _ = require("underscore");

var arr = [1,2,3,4,5,6];
// Testing _.shuffle
var testShuffle = function () {
  var indexOne = 0;
    var stObj = {
      '0': 0,
      '1': 1,
      '2': 2,
      '3': 3,
      '4': 4,
      '5': 5
    };
    for (var i = 0; i < 1000; i++) {
      arr = _.shuffle(arr);
      indexOne = _.indexOf(arr, 1);
      stObj[indexOne] ++;
    }
    console.log(stObj);
};
testShuffle();

Fisher Yates的这种变体稍微更有效,因为它避免了元素与自身的交换:

function shuffle(array) {
  var elementsRemaining = array.length, temp, randomIndex;
  while (elementsRemaining > 1) {
    randomIndex = Math.floor(Math.random() * elementsRemaining--);
    if (randomIndex != elementsRemaining) {
      temp = array[elementsRemaining];
      array[elementsRemaining] = array[randomIndex];
      array[randomIndex] = temp;
    }
  }
  return array;
}

社区表示arr.sort((a,b)=>0.5-Math.random())不是100%随机的!对我测试并建议不要使用此方法!

let arr = [1, 2, 3, 4, 5, 6]
arr.sort((a, b) => 0.5 - Math.random());

但我不确定。所以我写了一些代码来测试!。。。你也可以试试!如果你足够感兴趣!

让data_base=[];对于(设i=1;i<=100;i++){//将100次新的rendom arr推送到data_base!数据基础推送([1,2,3,4,5,6]排序((a,b)=>{return Math.random()-0.5;//使用了社区禁止的方法!:-)}));}//console.log(data_base);//如果你想看数据!让分析={};for(设i=1;i<=6;i++){analysis[i]=阵列(6).填充(0);}for(假设num=0;num<6;num++){for(设i=1;i<=100;i++){let plus=数据基[i-1][num];分析[`${num+1}`][plus-1]++;}}console.log(分析);//分析结果

在100个不同的随机阵列中。(我的分析结果)

{ player> 1   2   3  4   5   6
   '1': [ 36, 12, 17, 16, 9, 10 ],
   '2': [ 15, 36, 12, 18, 7, 12 ],
   '3': [ 11, 8, 22, 19, 17, 23 ],
   '4': [ 9, 14, 19, 18, 22, 18 ],
   '5': [ 12, 19, 15, 18, 23, 13 ],
   '6': [ 17, 11, 15, 11, 22, 24 ]
}  
// player 1 got > 1(36 times),2(15 times),...,6(17 times)
// ... 
// ...
// player 6 got > 1(10 times),2(12 times),...,6(24 times)

正如你所看到的,这不是那么随机!苏。。。不要使用此方法!如果你测试多次,你会看到玩家1获得了很多次(1号)!而球员6在大多数时候都获得了(第6名)!

递归解决方案:

function shuffle(a,b){
    return a.length==0?b:function(c){
        return shuffle(a,(b||[]).concat(c));
    }(a.splice(Math.floor(Math.random()*a.length),1));
};

事实上的无偏洗牌算法是Fisher Yates(又名Knuth)shuffle。

你可以在这里看到一个很棒的可视化效果(以及链接到此的原始帖子)

函数洗牌(数组){let currentIndex=array.length,randomIndex;//而还有一些元素需要洗牌。while(currentIndex!=0){//拾取剩余的元素。randomIndex=数学地板(Math.random()*当前索引);当前索引--;//并将其与当前元素交换。[array[currentIndex],array[randomIndex]]=[array[randomIndex],array[currentIndex]];}返回数组;}//如此使用var arr=[2,11,37,42];洗牌(arr);控制台日志(arr);

有关所用算法的更多信息。