You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
27 lines
726 B
27 lines
726 B
|
3 weeks ago
|
/**
|
||
|
|
* 加权随机选取
|
||
|
|
*/
|
||
|
|
export class WeightedPick {
|
||
|
|
/**
|
||
|
|
* 按 weight 加权随机一项;weight≤0 不参与
|
||
|
|
* @param list 候选列表
|
||
|
|
*/
|
||
|
|
static pick<T extends { weight?: number }>(list: T[]): T | null {
|
||
|
|
if (!list?.length) return null;
|
||
|
|
let total = 0;
|
||
|
|
for (const x of list) {
|
||
|
|
const w = Number(x.weight) || 0;
|
||
|
|
if (w > 0) total += w;
|
||
|
|
}
|
||
|
|
if (total <= 0) return null;
|
||
|
|
let r = Math.random() * total;
|
||
|
|
for (const x of list) {
|
||
|
|
const w = Number(x.weight) || 0;
|
||
|
|
if (w <= 0) continue;
|
||
|
|
r -= w;
|
||
|
|
if (r <= 0) return x;
|
||
|
|
}
|
||
|
|
return list[list.length - 1] ?? null;
|
||
|
|
}
|
||
|
|
}
|