Skip to content

Instantly share code, notes, and snippets.

@tangoabcdelta
Created August 7, 2022 13:32
Show Gist options
  • Save tangoabcdelta/42f5748099df58a65fbb1510fd2833db to your computer and use it in GitHub Desktop.
Save tangoabcdelta/42f5748099df58a65fbb1510fd2833db to your computer and use it in GitHub Desktop.
The Sindresorhus Approach for finding unique random elements from an Array
var input = [11, 12, 13, 55, 34, 66, 88, 12, 98, 67, 12, 66, 53, 23];
console.log(`input size is ${input.length}`);
(function theSindresorhusApproach() {
// the sindresorhus approach
function* play() {
let h = {};
input.map((i) => (h[i] = i));
h = Object.keys(h).map((i) => parseInt(i));
yield `unique elements size is ${h.length}, and elements are ${h}`;
for (let i = 0; i < h.length; i++) {
yield h[getRandomIndex(h.length)()];
}
}
// inspired by https://github.com/sindresorhus/unique-random/blob/main/index.js
function getRandomIndex(size) {
let previous;
return function () {
const number = Math.floor(Math.random() * size);
previous = number === previous ? getRandomIndex(size) : number;
return previous;
};
}
const iterator = play();
console.log(iterator.next().value);
console.log(iterator.next().value);
console.log(iterator.next().value);
console.log(iterator.next().value);
console.log(iterator.next().value);
console.log(iterator.next().value);
console.log(iterator.next().value);
console.log(iterator.next().value);
console.log(iterator.next().value);
console.log(iterator.next().value);
console.log(iterator.next().value);
console.log(iterator.next().value);
})();
@tangoabcdelta
Copy link
Author

It doesn't guarantee non-duplication beyond the immediate next iteration, however. i.e. in this approach, two subsequent elements won't be duplicates, but if you iterate further, you may encounter some.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment