Подтвердить что ты не робот

Как перетасовать символы в строке в JavaScript?

В частности, я хочу быть уверенным в том, чтобы избежать ошибки, произошедшей в коде Shuffle Microsoft Browser Choice. То есть, я хочу убедиться, что каждая буква имеет равную вероятность попадания в каждую возможную позицию.

например. Учитывая "ABCDEFG", верните что-то вроде "GEFBDCA".

4b9b3361

Ответ 1

Я изменил пример из записи 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 "

Более подробную информацию можно найти в ответ Jon Skeet Правильно ли использовать метод JavaScript Array.sort() для перетасовки?.

Ответ 2

Если "действительно" случайность важна, я рекомендую против этого. См. Мое нижнее правление.

Я просто хотел добавить свой любимый метод для небольшого разнообразия;)

С учетом строки:

var str = "My bologna has a first name, it 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 вообще, поскольку он страдает от кода "Microsoft Browser Choice shuffle". Это не очень хороший рандомизатор, если ваша строка должна быть близка к случайной. Тем не менее, это потрясающе, быстро "перебирая" ваши строки, где "истинная" случайность не имеет значения.

Статья, которую он приводит ниже, является отличным чтением, но объясняет совершенно другой случай использования, который влияет на статистические данные. Я лично не могу представить себе практическую проблему с использованием этой "случайной" функции в строке, но как кодер, вы несете ответственность за знание, когда не использовать это.

Я оставил это здесь для всех случайных рандомизаторов.

Ответ 3

Несмотря на то, что на этот вопрос уже дан ответ, я хотел бы поделиться решением, которое мне пришло в голову:

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'

Вы также можете попробовать это (jsfiddle).

Ответ 4

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

Ответ 5

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

Просто передайте строку функции и взамен получите перетасованную строку

Ответ 6

Другой подход к набору слов. Все остальные ответы с достаточным количеством итераций вернут слово без шифрования, а у меня - нет.

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

Ответ 7

Если вы любите аккуратные и красивые строки, как и я, вам может понравиться моя реализация 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));

Ответ 8

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