Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Most efficient array shuffler [duplicate]

How can I shuffle an array's values in the most efficient manner possible?

Each element is just a string containing HTML.

like image 422
Adam Lynch Avatar asked Sep 05 '11 14:09

Adam Lynch


3 Answers

You have a few choices.

First, you could use the stupidely naïve sorter...

arr = arr.sort(function() {
    return Math.random() - .5
});

jsFiddle.

This is quick and dirty but often considered bad practice.

Further Reading.

The best way to randomly sort an Array is with the Fisher-Yates shuffle.

var newArr = [];

while (arr.length) {

   var randomIndex = Math.floor(Math.random() * arr.length),
       element = arr.splice(randomIndex, 1)

   newArr.push(element[0]);       

}

JSBin.

like image 62
alex Avatar answered Sep 27 '22 21:09

alex


Let me post my own answer just to encourage you NOT TO use random sort() method as it will produce not so random output.

As being said, Fisher-Yates shuffle is the most efficient algorithm for that purpose, and it can be easily implemented with the following ES6 code:

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

      shuffle = arr => arr.reduceRight((r,_,__,s) => 
        (r.push(s.splice(0|Math.random()*s.length,1)[0]), r),[])

console.log(JSON.stringify(shuffle(src)))
.as-console-wrapper {min-height:100%}
like image 43
Yevgen Gorbunkov Avatar answered Sep 27 '22 21:09

Yevgen Gorbunkov


This is the one I use. It gives a random number to each element, sorts the array by those random numbers (moving the real values along) and then removes the random numbers again. It seems to be equally distributed, but I've not mathematically proven it yet.

arr = arr.map(function(v) {
    return [v, Math.random()];
}).sort(function(a, b) {
    return a[1] - b[1];
}).map(function(v) {
    return v[0];
});

http://jsfiddle.net/XQRFt/ - Test results (might be slow)

like image 27
pimvdb Avatar answered Sep 27 '22 19:09

pimvdb