Created
July 15, 2017 03:52
-
-
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/)
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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