如何在 JavaScript 中打乱字符串中的字符?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/3943772/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-23 06:46:32  来源:igfitidea点击:

How do I shuffle the characters in a string in JavaScript?

javascriptstring

提问by Liam

In particular, I want to make sure to avoid the mistake made in Microsoft's Browser Choiceshuffle code. That is, I want to make sure that each letter has an equal probability of ending up in each possible position.

特别是,我想确保避免在Microsoft 的 Browser Choiceshuffle 代码中犯的错误。也就是说,我想确保每个字母出现在每个可能位置的概率相等。

e.g. Given "ABCDEFG", return something like "GEFBDCA".

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

回答by Andy E

I modified an example from the Fisher-Yates Shuffle entry on Wikipediato shuffle strings:

我修改了Wikipedia 上 Fisher-Yates 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 "

More information can be found in Jon Skeet's answerto Is it correct to use JavaScript Array.sort() method for shuffling?.

更多信息可参见乔恩斯基特的回答是正确使用JavaScript的Array.sort()方法洗牌?.

回答by Joel Mellon

If "truly" randomness is important, I recommend against this. See my below edit.

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

I just wanted to add my favorite method for a little variety ;)

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

Given a string:

给定一个字符串:

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

Shuffle in one line:

在一行中随机播放:

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

Outputs:

输出:

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

EDIT: As @PleaseStand has pointed out, this doesn't meet OP's question at all since it does suffer from "Microsoft's Browser Choice shuffle" code. This isn't a very good randomizer if your string needs to be close to random. It is however, awesome at quickly "jumbling" your strings, where "true" randomness is irrelevant.

编辑:正如@PleaseStand 所指出的,这根本不符合OP 的问题,因为它确实受到“Microsoft 的浏览器选择洗牌”代码的影响。如果您的字符串需要接近随机,这不是一个很好的随机化器。然而,快速“混杂”你的字符串非常棒,“真正的”随机性是无关紧要的。

The article he links below is a great read, but explains a completely different use case, which affects statistical data. I personally can't imagine a practical issue with using this "random" function on a string but as a coder, you're responsible for knowing when notto use this.

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

I've left this here for all the casual randomizers out there.

我把这个留在这里给所有的随意随机化器。

回答by Maximilian Lindsey

Even though this has been answered, I wanted to share the solution I came up with:

即使已经回答了这个问题,我还是想分享我想出的解决方案:

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'

You can also try it out (jsfiddle).

你也可以试试 (jsfiddle)

回答by Ste

Just for the sake of completeness even though this may not be exactly what the OP was after as that particular question has already been answered.

只是为了完整起见,即使这可能不是 OP 所追求的,因为该特定问题已经得到回答。

Here's one that shuffles words.

这是一个洗牌的词。

Here's the regex explanation for that: https://regex101.com/r/aFcEtk/1

这是对此的正则表达式解释:https: //regex101.com/r/aFcEtk/1

And it also has some funny outcomes.

它也有一些有趣的结果。

// Shuffles words
// var str = "1 2 3 4 5 6 7 8 9 10";
var str = "the quick brown fox jumps over the lazy dog A.S.A.P. That's right, this happened.";
var every_word_im_shuffling = str.split(/\s\b(?!\s)/).sort(function(){return 0.5-Math.random()}).join(' ');
console.log(every_word_im_shuffling);

回答by chickens

Shortest One Liner:

最短的一个班轮:

let shuffled = str.split('').sort(()=>(Math.random()-0.5)).join('');

回答by Captain Fail

String.prototype.shuffle = function(){
  return this.split('').sort(function(a,b){
    return (7 - (Math.random()+'')[5]);
  }).join('');
};

回答by Darkrum

A different take on scrambling a word. All other answers with enough iterations will return the word unscrambled, mine does not.

打乱单词的不同看法。具有足够迭代次数的所有其他答案将返回 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

回答by Yevgen Gorbunkov

Yet another Fisher-Yatesimplementation:

另一个Fisher-Yates实现:

const str = 'ABCDEFG',

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

console.log(shuffle(str))
.as-console-wrapper{min-height:100%;}

回答by user1289673

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("");
}

回答by Mayur Nandane

                  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
                        }
                 };

Just pass the string to function and in return get the shuffled string

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