Skip to content

Instantly share code, notes, and snippets.

@sghiassy
Created July 15, 2017 03:52
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 sghiassy/a366cef6b8a82f858a6bbcb0300da41b to your computer and use it in GitHub Desktop.
Save sghiassy/a366cef6b8a82f858a6bbcb0300da41b to your computer and use it in GitHub Desktop.
A simple JavaScript implementation of Reservoir Sampling with any K length (http://www.geeksforgeeks.org/reservoir-sampling/)
class Node {
constructor(value, next) {
this.value = value;
this.next = next;
}
}
function getRandom(list, k) {
const reservoir = new Array(k);
for (let i = 0, ptr = list; ptr != undefined; i++, ptr = ptr.next) {
stream(reservoir, i, ptr);
}
return reservoir;
}
function stream(reservoir, n, input) {
if (n < reservoir.length) { // If we're still below the reservoir's threshold, then automatically put it in
reservoir[n] = input;
} else {
let r = randomIntInRange(0, n, true); // Generate a random number from 0 (inclusive) to N (inclusive)
if (r < reservoir.length) { // If the random number is within the reservoir's threshold range,
reservoir[r] = input;
}
}
}
function randomIntInRange(min, max, inclusive) {
const range = (max - min) + ((inclusive) ? 1 : 0);
return Math.trunc(Math.random() * range + min);
}
const linkedList = new Node('a',
new Node('b',
new Node('c',
new Node('d',
new Node('e')))));
const randomNode = getRandom(linkedList, 1); // We're setting K = 1, here since we're only picking a single node. But K can be higher for larger lists or streams.
console.log(`The randomly selected node is ${randomNode[0].value}`);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment