Skip to content

Instantly share code, notes, and snippets.

@steveharoz
Last active August 29, 2015 13:57
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save steveharoz/9403940 to your computer and use it in GitHub Desktop.
Save steveharoz/9403940 to your computer and use it in GitHub Desktop.
Shuffler
// Randomly samples an element from an array and prevents the same element
// from being returned twice unless separated by some number of samples
//
// Constructor parameters
// array: the original array to shuffle and use
// proximityLimit: minimum number of samples between returning the same element (max: array.length/2)
// Methods
// Next(): get the next item
//
// sample use:
// var myShuffler = new Shuffler([1,2,3,4,5,6,7,8,9,0], 3);
// var x = myShuffler.Next();
function Shuffler(array, proximityLimit) {
var original = array;
var similarRange = Math.min(proximityLimit, array.length/2);
var previous = [];
var current = [];
var currentIndex = 0;
// Fisher-Yates shuffle
function shuffle(array) {
var m = array.length, temp, i;
// While there remain elements to shuffle…
while (m) {
// Pick a remaining element…
i = Math.floor(Math.random() * m--);
// And swap it with the current element.
temp = array[m];
array[m] = array[i];
array[i] = temp;
}
return array;
}
// test if two arrays have any similar items
function testSimilar(array1, array2) {
for (var i = 0; i < array1.length; i++) {
if (array2.indexOf(array1[i]) >= 0)
return true;
}
return false;
}
// get the next set of shuffled items
function makeNewSet() {
previous = current;
var tailPrevious = previous.slice(previous.length - similarRange);
var headCurrent = [];
do {
current = shuffle(original);
headCurrent = current.slice(0, proximityLimit);
} while (testSimilar(tailPrevious, headCurrent))
}
// returns a random element
this.Next = function () {
if (currentIndex >= current.length) {
currentIndex = 0;
makeNewSet();
}
return current[currentIndex++];
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment