Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I shuffle an array? [duplicate]

Tags:

javascript

I want to shuffle an array of elements in JavaScript like these:

[0, 3, 3] -> [3, 0, 3] [9, 3, 6, 0, 6] -> [0, 3, 6, 9, 6] [3, 3, 6, 0, 6] -> [0, 3, 6, 3, 6] 
like image 795
Anshul Avatar asked Jun 08 '11 04:06

Anshul


People also ask

How do you optimally shuffle an array?

A simple solution is to create an auxiliary array temp[] which is initially a copy of arr[]. Randomly select an element from temp[], copy the randomly selected element to arr[0], and remove the selected element from temp[]. Repeat the same process n times and keep copying elements to arr[1], arr[2], … .

How do you remove duplicates from an array of arrays?

To remove duplicates from an array: First, convert an array of duplicates to a Set . The new Set will implicitly remove duplicate elements. Then, convert the set back to an array.

How do you prevent duplicate arrays?

To prevent adding duplicates to an array:Use the indexOf() method to check that the value is not present in the array. The indexOf method returns -1 if the value is not contained in the array. If the condition is met, push the value to the array.


2 Answers

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;     } }); 
like image 123
22 revs, 14 users 24% Avatar answered Sep 20 '22 16:09

22 revs, 14 users 24%


You could use the Fisher-Yates Shuffle (code adapted from this site):

function shuffle(array) {     let counter = array.length;      // While there are elements in the array     while (counter > 0) {         // Pick a random index         let index = Math.floor(Math.random() * counter);          // Decrease counter by 1         counter--;          // And swap the last element with it         let temp = array[counter];         array[counter] = array[index];         array[index] = temp;     }      return array; } 
like image 43
18 revs, 4 users 85% Avatar answered Sep 20 '22 16:09

18 revs, 4 users 85%