特别是,我想确保避免在Microsoft的Browser Choice shuffle代码中犯下的错误。也就是说,我想确保每个字母在每个可能的位置都有相同的概率。
例如给定“ABCDEFG”,返回类似“GEFBDCA”的内容。
我修改了一个从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?。
如果“真正”的随机性很重要,我建议不要这样做。请参阅下面的编辑。
我只想添加一些我最喜欢的方法;)
给定一个字符串:
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的问题,因为它确实遭受了“微软的浏览器选择洗牌”代码。如果你的字符串需要接近随机,这不是一个非常好的随机函数。然而,令人敬畏的是快速“混乱”你的字符串,其中“真正的”随机性是无关紧要的。
他在下面链接的文章是一个很好的阅读,但解释了一个完全不同的用例,它影响统计数据。我个人无法想象在字符串上使用这个“随机”函数的实际问题,但作为一个编码器,你有责任知道何时不使用它。
我已经把它留给了那里的所有休闲随机发生器。
虽然已经回答了这个问题,但我想分享一下我提出的解决方案:
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'
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("");
}
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
}
};
只需将字符串传递给函数,然后返回获取混洗字符串
争抢一个词的另一种看法。具有足够迭代的所有其他答案将返回单词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
如果你像我一样追求整洁美观的单行,你可能会喜欢我的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));
String.prototype.shuffle = function(){
return this.split('').sort(function(a,b){
return (7 - (Math.random()+'')[5]);
}).join('');
};