/* @flow */ /** * A [Fisher-Yates shuffle](http://en.wikipedia.org/wiki/Fisher%E2%80%93Yates_shuffle) * in-place - which means that it **will change the order of the original * array by reference**. * * This is an algorithm that generates a random [permutation](https://en.wikipedia.org/wiki/Permutation) * of a set. * * @param {Array} x sample of one or more numbers * @param {Function} [randomSource=Math.random] an optional entropy source that * returns numbers between 0 inclusive and 1 exclusive: the range [0, 1) * @returns {Array} x * @example * var x = [1, 2, 3, 4]; * shuffleInPlace(x); * // x is shuffled to a value like [2, 1, 4, 3] */ function shuffleInPlace( x /*: Array */, randomSource /*: ?Function */ ) /*: Array */ { // a custom random number source can be provided if you want to use // a fixed seed or another random number generator, like // [random-js](https://www.npmjs.org/package/random-js) randomSource = randomSource || Math.random; // store the current length of the x to determine // when no elements remain to shuffle. let length = x.length; // temporary is used to hold an item when it is being // swapped between indices. let temporary; // The index to swap at each stage. let index; // While there are still items to shuffle while (length > 0) { // chose a random index within the subset of the array // that is not yet shuffled index = Math.floor(randomSource() * length--); // store the value that we'll move temporarily temporary = x[length]; // swap the value at `x[length]` with `x[index]` x[length] = x[index]; x[index] = temporary; } return x; } export default shuffleInPlace;