How can I shuffle an array\'s values in the most efficient manner possible?
Each element is just a string containing HTML.
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.
This is my solution to shuffle an array:
function shuffle(array) {
var resultArray = new Array();
for(i=0;i<array.length;i++) {
var randomEle = Math.floor(Math.random()*array.length);
resultArray.push(array[randomEle]);
array.splice(randomEle,1);
}
resultArray = resultArray.concat(array);
return resultArray;
}
This is a shuffle contest to compare my method with the other 2
http://jsperf.com/shuffle-contest/2
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)
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%}