Skip to content

Instantly share code, notes, and snippets.

@jknopp
Created December 12, 2020 04:07
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 jknopp/18bc605e325742457fbd486c1ab81bf8 to your computer and use it in GitHub Desktop.
Save jknopp/18bc605e325742457fbd486c1ab81bf8 to your computer and use it in GitHub Desktop.
Randomly Select Item from Array Based on Frequency
// Define our array of object we want to randomly select from
const fallingItems =
[{
id: 1,
value: 150,
image: 'rare.png',
velocity: 5000,
size: 60
},
{
id: 2,
value: 25,
image: 'average.png',
velocity: 2000
size: 110
},
{
id: 3,
value: 2,
image: 'common.png',
velocity: 900,
size: 50
}];
// Define the freqeuncy we want each of the fallingItems to be occur at,
// relative to one another
const frequencyOfFallingItems = [2, 4, 8];
// Randomly get falling item based on frequency array
const itemToQueue =
arrayItemArbitraryProbabilityDistribution(fallingItems, frequencyOfFallingItems);
// Utility function to find index of {random} in prefix[start..end]
function findRandomInPrefixArray(prefix, random, start, end) {
let mid;
while (start < end) {
mid = Math.floor((start + end) / 2);
if (random > prefix[mid]) {
start = mid + 1;
} else {
end = mid;
}
}
return (prefix[start] >= random) ? start : -1;
}
// Returns a random item from array[]
// according to distribution array
// defined by frequency[].
export const arrayItemArbitraryProbabilityDistribution = (array, frequency) => {
const size = array.length;
// Create and fill prefix array
let prefix = [];
prefix[0] = frequency[0];
for (let i = 1; i < size; ++i) {
prefix[i] = prefix[i - 1] + frequency[i];
}
// prefix[n-1] is sum of all frequencies.
// Generate a random number with
// value from 1 to this sum
const random = ((Math.floor((Math.random() * 323567))) % prefix[size - 1]) + 1;
// Find find index of {random} in prefix array
const index = findRandomInPrefixArray(prefix, random, 0, size - 1);
return array[index];
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment