@technobuddha/library
Version:
A large library of useful functions
39 lines • 2.51 kB
JavaScript
/**
* Selects a random item from a list, where each item has an associated weight that determines its likelihood of being picked.
*
* If the list is empty, it returns `undefined`.
* @typeParam T - The type of items in the list, extending the `Weighted` interface (must have a `weight` property).
* @param list - The array of weighted items to pick from.
* @param random - A function that returns a random number between 0 (inclusive) and 1 (exclusive). Defaults to `Math.random`.
* @returns The randomly selected item based on weights, or `undefined` if the list is empty.
* @group Random
* @category Pick
* @example
* ```typescript
* const items = [
* { value: 'a', weight: 1 },
* { value: 'b', weight: 3 },
* { value: 'c', weight: 6 },
* ];
* randomWeightedPick(items, () => 0.0); // { value: 'a', weight: 1 }
* randomWeightedPick(items, () => 0.2); // { value: 'b', weight: 3 }
* randomWeightedPick(items, () => 0.8); // { value: 'c', weight: 6 }
* randomWeightedPick([], () => 0.5); // undefined
* ```
*/
export function randomWeightedPick(list, random = Math.random) {
if (list.length === 0) {
return undefined;
}
const totalWeight = list.reduce((sum, item) => sum + (item.weight ?? 0), 0);
const index = random() * totalWeight;
let cumulativeWeight = 0;
for (const item of list) {
cumulativeWeight += item.weight ?? 0;
if (index < cumulativeWeight) {
return item;
}
}
return undefined;
}
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicmFuZG9tLXdlaWdodGVkLXBpY2suanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi9zcmMvcmFuZG9tLXdlaWdodGVkLXBpY2sudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBZUE7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7R0FzQkc7QUFDSCxNQUFNLFVBQVUsa0JBQWtCLENBQ2hDLElBQWtCLEVBQ2xCLFNBQXVCLElBQUksQ0FBQyxNQUFNO0lBRWxDLElBQUksSUFBSSxDQUFDLE1BQU0sS0FBSyxDQUFDLEVBQUUsQ0FBQztRQUN0QixPQUFPLFNBQVMsQ0FBQztJQUNuQixDQUFDO0lBRUQsTUFBTSxXQUFXLEdBQUcsSUFBSSxDQUFDLE1BQU0sQ0FBQyxDQUFDLEdBQUcsRUFBRSxJQUFJLEVBQUUsRUFBRSxDQUFDLEdBQUcsR0FBRyxDQUFDLElBQUksQ0FBQyxNQUFNLElBQUksQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUM7SUFDNUUsTUFBTSxLQUFLLEdBQUcsTUFBTSxFQUFFLEdBQUcsV0FBVyxDQUFDO0lBRXJDLElBQUksZ0JBQWdCLEdBQUcsQ0FBQyxDQUFDO0lBQ3pCLEtBQUssTUFBTSxJQUFJLElBQUksSUFBSSxFQUFFLENBQUM7UUFDeEIsZ0JBQWdCLElBQUksSUFBSSxDQUFDLE1BQU0sSUFBSSxDQUFDLENBQUM7UUFDckMsSUFBSSxLQUFLLEdBQUcsZ0JBQWdCLEVBQUUsQ0FBQztZQUM3QixPQUFPLElBQUksQ0FBQztRQUNkLENBQUM7SUFDSCxDQUFDO0lBRUQsT0FBTyxTQUFTLENBQUM7QUFDbkIsQ0FBQyJ9