Как рандомизировать (перемешать) массив JavaScript? - PullRequest
1065 голосов
/ 16 марта 2010

У меня есть такой массив:

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

Как я могу рандомизировать / перемешать это?

Ответы [ 50 ]

2 голосов
/ 21 октября 2015
var shuffledArray = function(inpArr){
    //inpArr - is input array
    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{
        //generate random index between range
        tempInd = Math.floor(Math.random() * (max - min));
        //check if index is already available in array to avoid repetition
        if(arrTempInd.indexOf(tempInd)<0){
            //push character at random index
            arrRand[i] = inpArr[tempInd];
            //push random indexes
            arrTempInd.push(tempInd);
            i++;
        }
    }
    // check if random array length is equal to input array length
    while(arrTempInd.length < max){
        return arrRand; // this will return shuffled Array
    }
};

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

2 голосов
/ 07 мая 2015

Рандомизированный массив

 var arr = ['apple','cat','Adam','123','Zorro','petunia']; 
 var n = arr.length; var tempArr = [];

 for ( var i = 0; i < n-1; i++ ) {

    // The following line removes one random element from arr 
     // and pushes it onto tempArr 
     tempArr.push(arr.splice(Math.floor(Math.random()*arr.length),1)[0]);
 }

 // Push the remaining item onto tempArr 
 tempArr.push(arr[0]); 
 arr=tempArr; 
2 голосов
/ 16 июня 2016

Учитывая его применение к в loco или к новому неизменяемому массиву, следуя другим решениям, вот предлагаемая реализация:

Array.prototype.shuffle = function(local){
  var a = this;
  var newArray = typeof local === "boolean" && local ? this : [];
  for (var i = 0, newIdx, curr, next; i < a.length; i++){
    newIdx = Math.floor(Math.random()*i);
    curr = a[i];
    next = a[newIdx];
    newArray[i] = next;
    newArray[newIdx] = curr;
  }
  return newArray;
};
2 голосов
/ 24 июля 2016

Рональд Фишер и Фрэнк Йейтс перемешивают

ES2015 (ES6) выпуск

Array.prototype.shuffle2 = function () {
    this.forEach(
        function (v, i, a) {
            let j = Math.floor(Math.random() * (i + 1));
            [a[i], a[j]] = [a[j], a[i]];
        }
    );
    return this;
}

Jet оптимизированный выпуск ES2015 (ES6)

Array.prototype.shuffle3 = function () {
    var m = this.length;
    while (m) {
        let i = Math.floor(Math.random() * m--);
        [this[m], this[i]] = [this[i], this[m]];
    }
    return this;
}
2 голосов
/ 12 ноября 2016

Я вижу, что еще никто не дал решение, которое можно объединить, не расширяя прототип Array (что является плохой практикой ). Используя немного менее известную reduce(), мы можем легко сделать тасование способом, который учитывает конкатенацию:

var randomsquares = [1, 2, 3, 4, 5, 6, 7].reduce(shuffle).map(n => n*n);

Возможно, вы захотите передать второй параметр [], иначе, если вы попытаетесь сделать это на пустом массиве, он потерпит неудачу:

// Both work. The second one wouldn't have worked as the one above
var randomsquares = [1, 2, 3, 4, 5, 6, 7].reduce(shuffle, []).map(n => n*n);
var randomsquares = [].reduce(shuffle, []).map(n => n*n);

Давайте определим shuffle как:

var shuffle = (rand, one, i, orig) => {
  if (i !== 1) return rand;  // Randomize it only once (arr.length > 1)

  // You could use here other random algorithm if you wanted
  for (let i = orig.length; i; i--) {
    let j = Math.floor(Math.random() * i);
    [orig[i - 1], orig[j]] = [orig[j], orig[i - 1]];
  }

  return orig;
}

Вы можете увидеть это в действии в JSFiddle или здесь:

var shuffle = (all, one, i, orig) => {
    if (i !== 1) return all;

    // You could use here other random algorithm here
    for (let i = orig.length; i; i--) {
        let j = Math.floor(Math.random() * i);
        [orig[i - 1], orig[j]] = [orig[j], orig[i - 1]];
    }

    return orig;
}

for (var i = 0; i < 5; i++) {
  var randomarray = [1, 2, 3, 4, 5, 6, 7].reduce(shuffle, []);
  console.log(JSON.stringify(randomarray));
}
2 голосов
/ 19 ноября 2014

Рандомизировать массив с помощью array.splice ()

function shuffleArray(array) {
   var temp = [];
   var len=array.length;
   while(len){
      temp.push(array.splice(Math.floor(Math.random()*array.length),1)[0]);
      len--;
   }
   return temp;
}
//console.log("Here >>> "+shuffleArray([4,2,3,5,8,1,0]));

демо

2 голосов
/ 14 апреля 2017

function shuffleArray(array) {
        // Create a new array with the length of the given array in the parameters
        const newArray = array.map(() => null);

        // Create a new array where each index contain the index value
        const arrayReference = array.map((item, index) => index);

        // Iterate on the array given in the parameters
        array.forEach(randomize);
        
        return newArray;

        function randomize(item) {
            const randomIndex = getRandomIndex();

            // Replace the value in the new array
            newArray[arrayReference[randomIndex]] = item;
            
            // Remove in the array reference the index used
            arrayReference.splice(randomIndex,1);
        }

        // Return a number between 0 and current array reference length
        function getRandomIndex() {
            const min = 0;
            const max = arrayReference.length;
            return Math.floor(Math.random() * (max - min)) + min;
        }
    }
    
console.log(shuffleArray([10,20,30,40,50,60,70,80,90,100]));
2 голосов
/ 22 февраля 2017

Я думал о том, чтобы oneliner вставить в консоль. Все трюки с .sort давали неверные результаты, вот моя реализация:

 ['Bob', 'Amy', 'Joy'].map((person) => `${Math.random().toFixed(10)}${person}`).sort().map((person) => person.substr(12));

Но не используйте его в рабочем коде, он не оптимален и работает только со строками.

2 голосов
/ 21 декабря 2018

Для тех из нас, кто не очень одарен, но имеет доступ к чудесам Лодаша, есть такая вещь, как lodash.shuffle .

2 голосов
/ 23 апреля 2018

Используя модуль shuffle-array , вы можете перемешать ваш массив. Вот простой код этого.

var shuffle = require('shuffle-array'),
 //collection = [1,2,3,4,5];
collection = ["a","b","c","d","e"];
shuffle(collection);

console.log(collection);

Надеюсь, это поможет.

...