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

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

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

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

Ответы [ 50 ]

1 голос
/ 09 мая 2019

Восстановление всего массива, один за другим, помещая каждый элемент в произвольное место.

[1,2,3].reduce((a,x,i)=>{a.splice(Math.floor(Math.random()*(i+1)),0,x);return a},[])

var ia= [1,2,3];
var it= 1000;
var f = (a,x,i)=>{a.splice(Math.floor(Math.random()*(i+1)),0,x);return a};
var a = new Array(it).fill(ia).map(x=>x.reduce(f,[]));
var r = new Array(ia.length).fill(0).map((x,i)=>a.reduce((i2,x2)=>x2[i]+i2,0)/it)

console.log("These values should be quite equal:",r);
1 голос
/ 11 апреля 2019

Случайным образом либо толкать, либо снимать (добавить в начале).

['a', 'b', 'c', 'd'].reduce((acc, el) => {
  Math.random() > 0.5 ? acc.push(el) : acc.unshift(el);
  return acc;
}, []);
1 голос
/ 04 августа 2014

Эта вариация Фишера-Йейтса несколько более эффективна, поскольку позволяет избежать замены элемента на себя:

function shuffle(array) {
  var elementsRemaining = array.length, temp, randomIndex;
  while (elementsRemaining > 1) {
    randomIndex = Math.floor(Math.random() * elementsRemaining--);
    if (randomIndex != elementsRemaining) {
      temp = array[elementsRemaining];
      array[elementsRemaining] = array[randomIndex];
      array[randomIndex] = temp;
    }
  }
  return array;
}
1 голос
/ 07 августа 2018

d3.js предоставляет встроенную версию шагала Фишера-Йетса :

console.log(d3.shuffle(["a", "b", "c", "d"]));
<script src="http://d3js.org/d3.v5.min.js"></script>

d3.shuffle (массив [, lo [, hi]]) <>

Рандомизирует порядок указанного массива, используя случай Фишера – Йейтса .

1 голос
/ 29 января 2018

Я написал функцию перемешивания самостоятельно. Разница здесь в том, что она никогда не будет повторять значение (проверяет код для этого): -

function shuffleArray(array) {
 var newArray = [];
 for (var i = 0; i < array.length; i++) {
     newArray.push(-1);
 }

 for (var j = 0; j < array.length; j++) {
    var id = Math.floor((Math.random() * array.length));
    while (newArray[id] !== -1) {
        id = Math.floor((Math.random() * array.length));
    }

    newArray.splice(id, 1, array[j]);
 }
 return newArray; }
0 голосов
/ 25 июня 2019

Мы по-прежнему перетасовываем массивы в 2019 году, так что вот мой подход, который мне кажется аккуратным и быстрым :

const src = [...'abcdefg'];

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

console.log(shuffle(src));
.as-console-wrapper {
  max-height: 100% !important;
  top: 0;
}
0 голосов
/ 05 июня 2019
[1, 2, 3, 4, 5, 6, 7, 8, 9, 0].sort((x, z) => {
    ren = Math.random();
    if (ren == 0.5) return 0;
    return ren > 0.5 ? 1 : -1
})
0 голосов
/ 18 апреля 2019

Перемешать массив строк:

shuffle = (array) => {
  let counter = array.length, temp, index;
  while ( counter > 0 ) {
    index = Math.floor( Math.random() * counter );
    counter--;
    temp = array[ counter ];
    array[ counter ] = array[ index ];
    array[ index ] = temp;
  }
  return array;
 }
0 голосов
/ 03 октября 2018

Функциональное решение с использованием Ramda.

const {map, compose, sortBy, prop} = require('ramda')

const shuffle = compose(
  map(prop('v')),
  sortBy(prop('i')),
  map(v => ({v, i: Math.random()}))
)

shuffle([1,2,3,4,5,6,7])
0 голосов
/ 25 июля 2016

$=(m)=>console.log(m);

//----add this method to Array class 
Array.prototype.shuffle=function(){
  return this.sort(()=>.5 - Math.random());
};

$([1,65,87,45,101,33,9].shuffle());
$([1,65,87,45,101,33,9].shuffle());
$([1,65,87,45,101,33,9].shuffle());
$([1,65,87,45,101,33,9].shuffle());
$([1,65,87,45,101,33,9].shuffle());
...