How to Randomize (Shuffle) a JavaScript Array

How to randomize (shuffle) a JavaScript array?

The de-facto unbiased shuffle algorithm is the Fisher-Yates (aka Knuth) Shuffle.

You can see a great visualization here (and the original post linked to this)

function shuffle(array) {
let currentIndex = array.length, randomIndex;

// While there remain elements to shuffle.
while (currentIndex != 0) {

// Pick a remaining element.
randomIndex = Math.floor(Math.random() * currentIndex);
currentIndex--;

// And swap it with the current element.
[array[currentIndex], array[randomIndex]] = [
array[randomIndex], array[currentIndex]];
}

return array;
}

// Used like so
var arr = [2, 11, 37, 42];
shuffle(arr);
console.log(arr);

How to randomize (shuffle) a JavaScript array?

The de-facto unbiased shuffle algorithm is the Fisher-Yates (aka Knuth) Shuffle.

You can see a great visualization here (and the original post linked to this)

function shuffle(array) {
let currentIndex = array.length, randomIndex;

// While there remain elements to shuffle.
while (currentIndex != 0) {

// Pick a remaining element.
randomIndex = Math.floor(Math.random() * currentIndex);
currentIndex--;

// And swap it with the current element.
[array[currentIndex], array[randomIndex]] = [
array[randomIndex], array[currentIndex]];
}

return array;
}

// Used like so
var arr = [2, 11, 37, 42];
shuffle(arr);
console.log(arr);

How can I shuffle an array?

Use the modern version of the Fisher–Yates shuffle algorithm:

/**
* Shuffles array in place.
* @param {Array} a items An array containing the items.
*/
function shuffle(a) {
var j, x, i;
for (i = a.length - 1; i > 0; i--) {
j = Math.floor(Math.random() * (i + 1));
x = a[i];
a[i] = a[j];
a[j] = x;
}
return a;
}

ES2015 (ES6) version

/**
* Shuffles array in place. ES6 version
* @param {Array} a items An array containing the items.
*/
function shuffle(a) {
for (let i = a.length - 1; i > 0; i--) {
const j = Math.floor(Math.random() * (i + 1));
[a[i], a[j]] = [a[j], a[i]];
}
return a;
}

Note however, that swapping variables with destructuring assignment causes significant performance loss, as of October 2017.

Use

var myArray = ['1','2','3','4','5','6','7','8','9'];
shuffle(myArray);

Implementing prototype

Using Object.defineProperty (method taken from this SO answer) we can also implement this function as a prototype method for arrays, without having it show up in loops such as for (i in arr). The following will allow you to call arr.shuffle() to shuffle the array arr:

Object.defineProperty(Array.prototype, 'shuffle', {
value: function() {
for (let i = this.length - 1; i > 0; i--) {
const j = Math.floor(Math.random() * (i + 1));
[this[i], this[j]] = [this[j], this[i]];
}
return this;
}
});

How can I shuffle a JavaScript array?

I think the problem is that you need to do something like:

this.cards.sort((a,b) => 0.5 - Math.random());

based on some previous answers on SE

Or do something like this:

 this.cards.sort(() => Math.random() - 0.5);

Based on this SE Query

How can I sort an array randomly in javascript?

First of all, You're welcome to stackoverflow!

You can look at this question: Sorting an Array in Random Order

You can sort an array in a random order by providing a custom compare function:

var points = [1, 2, 3, 4, 5];
points.sort(function(a, b){return 0.5 - Math.random()});

But the above example is not accurate, it will favor some numbers over the others.

The most popular correct method, is the Fisher Yates shuffle:

var points = [40, 100, 1, 5, 25, 10];

for (i = points.length -1; i > 0; i--) {
j = Math.floor(Math.random() * i)
k = points[i]
points[i] = points[j]
points[j] = k
}

JavaScript array shuffling - why does the random number have to be shifted 0.5 down to a negative range?

If you want to look behind the curtain an analyze this through the lens of the particular sorting algorithm being used, you can't. The ECMAscript standard does not specify which sort algorithm browsers have to use for JavaScript's sort algorithm, so Firefox might do it one way while Chrome does it another. And then Chrome might change to do it differently later down the line. We just have to accept that level of abstraction.

Now, the are things that we do know. JavaScript allows us to provide a "comparison" function to be used when sorting arrays. you can pass two arguments into that comparison function and return a result to signal which value should appear first in the resulting array.

  • Returning a negative number signals that the first argument should occur earlier in the sorted array.
  • Returning a positive number signals that the second argument should occur earlier in the sorted array.
  • Returning zero signals that the two values are the same and should appear next to each other in the sorted array.

Here's a little snippet to exemplify these rules:

var arr = ["w", "l", "w"];
arr.sort(function(a, b){
if(a === b) return 0; //they're the same
if(a === "w") return -1; //w should appear earlier
return 1; //l should appear later
});

console.log(arr);

Picking array based off of percentage and shuffling it

  1. Your shuffle routine should probably return a new array with the results.

  2. You need to declare thing, and not use a global variable.

if (percent >= 0 && percent < 20) {
const thing = shuffle(tierOne)
return thing[0];
}

or

let thing
if (percent >= 0 && percent < 20) {
thing = shuffle(tierOne)
return thing[0];
}

How to shuffle an array with duplicate items, but duplicates can't be back to back

If you don't care about the execution time of the algorithm, just shuffle a few times until you get the result you want