How to Shuffle an Array

Random shuffling of an array

Using Collections to shuffle an array of primitive types is a bit of an overkill...

It is simple enough to implement the function yourself, using for example the Fisher–Yates shuffle:

import java.util.*;
import java.util.concurrent.ThreadLocalRandom;

class Test
{
public static void main(String args[])
{
int[] solutionArray = { 1, 2, 3, 4, 5, 6, 16, 15, 14, 13, 12, 11 };

shuffleArray(solutionArray);
for (int i = 0; i < solutionArray.length; i++)
{
System.out.print(solutionArray[i] + " ");
}
System.out.println();
}

// Implementing Fisher–Yates shuffle
static void shuffleArray(int[] ar)
{
// If running on Java 6 or older, use `new Random()` on RHS here
Random rnd = ThreadLocalRandom.current();
for (int i = ar.length - 1; i > 0; i--)
{
int index = rnd.nextInt(i + 1);
// Simple swap
int a = ar[index];
ar[index] = ar[i];
ar[i] = a;
}
}
}

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);

Shuffle an array with python, randomize array item order with python

import random
random.shuffle(array)

How to shuffle an array in C++?

Here's your code with what I felt were the smallest amount of changes. One could argue that I didn't need to change your first for loop as much, but I figure that if you have the prescience to know how many names you're reading, you might as well use the knowledge.

#include <algorithm>
#include <fstream>
#include <iostream>
#include <iterator> // std::begin(), std::end(); required for C-arrays
#include <random> // std::mt19937; needed to feed std::shuffle()
#include <string>
// using namespace std; // BAD PRACTICE

int main() {
constexpr int size = 4; // Give your magic number a name; only need to change
// a single location
std::ifstream readName("names.txt");
if (!readName) { // Always check that you successfully opened the file.
std::cerr << "Error opening file.\n";
return 1;
}

std::string names[size];
// int i = 0;
for (int i = 0; i < size; ++i) { // Retool the loop entirely
std::getline(readName, names[i]);
}
readName.close();

// This is a fragile solution. It's only working because the array is in
// scope
std::shuffle(std::begin(names), std::end(names),
std::mt19937{std::random_device{}()});

for (int i = 0; i < size; i++) {
std::cout << names[i]
<< '\n'; // Don't use std::endl unless you actually need it
}
return 0;
}

This is not ideal code, though. Any change to the size of the input file requires changing the code and re-compiling. The biggest single change was to get rid of std::random_shuffle and use std::shuffle() instead. std::random_shuffle was deprecated with C++14 and removed in C++17. It's bad to use it. std::shuffle() does add the requirement of providing a PRNG, but it's not so bad. It leads to better code if you have a PRNG that needs to randomize many different things in a bigger program. This is because it's good to have a single PRNG and let it live for the length of your program as opposed to constantly building new ones.

And the C-array just makes things a bit clunkier. Enter std::vector.

#include <algorithm>
#include <fstream>
#include <iostream>
#include <iterator>
#include <random> // std::mt19937; needed to feed std::shuffle()
#include <string>
#include <vector>

int main() {
std::ifstream readName("names.txt");
if (!readName) { // Always check that you successfully opened the file.
std::cerr << "Error opening file.\n";
return 1;
}

std::vector<std::string> names;
std::string name;
while (std::getline(readName, name)) { // Retool the loop entirely
names.push_back(name);
}
readName.close();

std::shuffle(std::begin(names), std::end(names),
std::mt19937{std::random_device{}()});

for (const auto& i : names) {
std::cout << i << '\n';
}

return 0;
}

The vector can grow as needed, so you see how much simpler the loop that reads the names becomes. It's also more flexible since you don't have to know ahead of time how many entries to expect. It will "just work." With the call to std::shuffle() I kept the std::begin(names) syntax because many consider this a best practice, but you could have also used names.begin() if you wanted since the vector class provides its own iterators.

Shuffle array in C

Pasted from Asmodiel's link to Ben Pfaff's Writings, for persistence:

#include <stdlib.h>

/* Arrange the N elements of ARRAY in random order.
Only effective if N is much smaller than RAND_MAX;
if this may not be the case, use a better random
number generator. */
void shuffle(int *array, size_t n)
{
if (n > 1)
{
size_t i;
for (i = 0; i < n - 1; i++)
{
size_t j = i + rand() / (RAND_MAX / (n - i) + 1);
int t = array[j];
array[j] = array[i];
array[i] = t;
}
}
}

EDIT: And here's a generic version that works for any type (int, struct, ...) through memcpy. With an example program to run, it requires VLAs, not every compiler supports this so you might want to change that to malloc (which will perform badly) or a static buffer large enough to accommodate any type you throw at it:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>

/* compile and run with
* cc shuffle.c -o shuffle && ./shuffle */

#define NELEMS(x) (sizeof(x) / sizeof(x[0]))

/* arrange the N elements of ARRAY in random order.
* Only effective if N is much smaller than RAND_MAX;
* if this may not be the case, use a better random
* number generator. */
static void shuffle(void *array, size_t n, size_t size) {
char tmp[size];
char *arr = array;
size_t stride = size * sizeof(char);

if (n > 1) {
size_t i;
for (i = 0; i < n - 1; ++i) {
size_t rnd = (size_t) rand();
size_t j = i + rnd / (RAND_MAX / (n - i) + 1);

memcpy(tmp, arr + j * stride, size);
memcpy(arr + j * stride, arr + i * stride, size);
memcpy(arr + i * stride, tmp, size);
}
}
}

#define print_type(count, stmt) \
do { \
printf("["); \
for (size_t i = 0; i < (count); ++i) { \
stmt; \
} \
printf("]\n"); \
} while (0)

struct cmplex {
int foo;
double bar;
};

int main() {
srand(time(NULL));

int intarr[] = { 1, -5, 7, 3, 20, 2 };

print_type(NELEMS(intarr), printf("%d,", intarr[i]));
shuffle(intarr, NELEMS(intarr), sizeof(intarr[0]));
print_type(NELEMS(intarr), printf("%d,", intarr[i]));

struct cmplex cmparr[] = {
{ 1, 3.14 },
{ 5, 7.12 },
{ 9, 8.94 },
{ 20, 1.84 }
};

print_type(NELEMS(intarr), printf("{%d %f},", cmparr[i].foo, cmparr[i].bar));
shuffle(cmparr, NELEMS(cmparr), sizeof(cmparr[0]));
print_type(NELEMS(intarr), printf("{%d %f},", cmparr[i].foo, cmparr[i].bar));

return 0;
}

How to shuffle the contents of an array

String[] names = ...;
Collections.shuffle(Arrays.asList(names));
// done

Note that Arrays.asList() returns a modifiable (but fixed-length) list, backed by the array, and not a copy of the array. So the array will be shuffled.

Shuffle an Array and Return a New One in JS

The easiest way I know of to create a copy of an array is using:

var newArray = [].concat(originalArray);

You could perform that in the first line of most of the solutions on the linked answer and you would be getting a new array back with the original untouched. Here is a modified version of the top rated answer on the linked question:

function shuffle(originalArray) {
var array = [].concat(originalArray);
var currentIndex = array.length, temporaryValue, randomIndex;

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

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

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

return array;
}

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;
}
});


Related Topics



Leave a reply



Submit