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
Your shuffle routine should probably return a new array with the results.
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
let arr = [1, 2, 2, 3, 4, 4, 5];
const hasDublicateItems = (arr) => arr.some((v, i, a) => v === a[i+1]);
while (hasDublicateItems(arr))
arr = arr.sort(() => (Math.random() > .5) ? 1 : -1);
console.log(arr);
.as-console-wrapper{min-height: 100%!important; top: 0}
Related Topics
How Does the "This" Keyword Work, and When Should It Be Used
What Is the Explicit Promise Construction Antipattern and How to Avoid It
What Is the Scope of Variables in JavaScript
Are 'Arrow Functions' and 'Functions' Equivalent/Interchangeable
Why Does Date.Parse Give Incorrect Results
How to Open a Native iOS App from a Web App
Node.Js App Can't Run on Port 80 Even Though There's No Other Process Blocking the Port
Ways to Circumvent the Same-Origin Policy
How to Upload Files Asynchronously With Jquery
Sort Array of Objects by String Property Value
Css Transition Doesn't Work If Element Start Hidden
Force "Landscape" Orientation Mode
Difference Between "Let" and "Var"
How to Loop Through or Enumerate a JavaScript Object
How to Start Automatic Download of a File in Internet Explorer
Set Webkit Keyframes Values Using JavaScript Variable