如何在JavaScript中对字符串中的字符进行随机播放?

问题描述 投票:38回答:8

特别是,我想确保避免在Microsoft的Browser Choice shuffle代码中犯下的错误。也就是说,我想确保每个字母在每个可能的位置都有相同的概率。

例如给定“ABCDEFG”,返回类似“GEFBDCA”的内容。

javascript string
8个回答
70
投票

我修改了一个从Fisher-Yates Shuffle entry on Wikipedia到shuffle字符串的例子:

String.prototype.shuffle = function () {
    var a = this.split(""),
        n = a.length;

    for(var i = n - 1; i > 0; i--) {
        var j = Math.floor(Math.random() * (i + 1));
        var tmp = a[i];
        a[i] = a[j];
        a[j] = tmp;
    }
    return a.join("");
}
console.log("the quick brown fox jumps over the lazy dog".shuffle());
//-> "veolrm  hth  ke opynug tusbxq ocrad ofeizwj"

console.log("the quick brown fox jumps over the lazy dog".shuffle());
//-> "o dt hutpe u iqrxj  yaenbwoolhsvmkcger ozf "

更多信息可以在Jon Skeet's answer找到Is it correct to use JavaScript Array.sort() method for shuffling?


37
投票

如果“真正”的随机性很重要,我建议不要这样做。请参阅下面的编辑。

我只想添加一些我最喜欢的方法;)

给定一个字符串:

var str = "My bologna has a first name, it's O S C A R.";

洗牌一行:

var shuffled = str.split('').sort(function(){return 0.5-Math.random()}).join('');

输出:

oa, a si'rSRn f gbomi. aylt AtCnhO ass eM
as'oh ngS li Ays.rC nRamsb Oo ait a ,eMtf
y alCOSf e gAointsorasmn bR Ms .' ta ih,a

编辑:正如@PleaseStand指出的那样,这根本不符合OP的问题,因为它确实遭受了“微软的浏览器选择洗牌”代码。如果你的字符串需要接近随机,这不是一个非常好的随机函数。然而,令人敬畏的是快速“混乱”你的字符串,其中“真正的”随机性是无关紧要的。

他在下面链接的文章是一个很好的阅读,但解释了一个完全不同的用例,它影响统计数据。我个人无法想象在字符串上使用这个“随机”函数的实际问题,但作为一个编码器,你有责任知道何时不使用它。

我已经把它留给了那里的所有休闲随机发生器。


6
投票

虽然已经回答了这个问题,但我想分享一下我提出的解决方案:

function shuffelWord (word){
    var shuffledWord = '';
    word = word.split('');
    while (word.length > 0) {
      shuffledWord +=  word.splice(word.length * Math.random() << 0, 1);
    }
    return shuffledWord;
}

// 'Batman' => 'aBmnta'

你也可以try it out (jsfiddle)


0
投票
String.prototype.shuffle=function(){

   var that=this.split("");
   var len = that.length,t,i
   while(len){
    i=Math.random()*len-- |0;
    t=that[len],that[len]=that[i],that[i]=t;
   }
   return that.join("");
}

0
投票
                  shuffleString = function(strInput){
                     var inpArr = strInput.split("");//this will give array of input string
                     var arrRand = []; //this will give shuffled array
                     var arrTempInd = []; // to store shuffled indexes
                     var max = inpArr.length;
                     var min = 0;
                     var tempInd;
                     var i =0 ;

                      do{
                           tempInd = Math.floor(Math.random() * (max - min));//to generate random index between range
                           if(arrTempInd.indexOf(tempInd)<0){ //to check if index is already available in array to avoid repeatation
                                arrRand[i] = inpArr[tempInd]; // to push character at random index
                                arrTempInd.push(tempInd); //to push random indexes 
                                i++;
                            }
                       }
                        while(arrTempInd.length < max){ // to check if random array lenght is equal to input string lenght
                            return arrRand.join("").toString(); // this will return shuffled string
                        }
                 };

只需将字符串传递给函数,然后返回获取混洗字符串


0
投票

争抢一个词的另一种看法。具有足够迭代的所有其他答案将返回单词unscrambled,而我的不会。

var scramble = word => {

    var unique = {};
    var newWord = "";
    var wordLength = word.length;

    word = word.toLowerCase(); //Because why would we want to make it easy for them?

    while(wordLength != newWord.length) {

        var random = ~~(Math.random() * wordLength);

        if(

          unique[random]
          ||
          random == newWord.length && random != (wordLength - 1) //Don't put the character at the same index it was, nore get stuck in a infinite loop.

        ) continue; //This is like return but for while loops to start over.

        unique[random] = true;
        newWord += word[random];

    };

    return newWord;

};

scramble("God"); //dgo, gdo, ogd

0
投票

如果你像我一样追求整洁美观的单行,你可能会喜欢我的ES6实现:

const str = 'ABCDEFG';

const shuffle = str => [...str].reduceRight((res,_,__,arr) => [...res,arr.splice(~~(Math.random()*arr.length),1)[0]],[]).join('');

console.log(shuffle(str));

-1
投票
String.prototype.shuffle = function(){
  return this.split('').sort(function(a,b){
    return (7 - (Math.random()+'')[5]);
  }).join('');
};
© www.soinside.com 2019 - 2024. All rights reserved.