JavaScript随机数生成器仅返回1或2无法遍历全部可选值问题排查
问题排查结果
核心问题原因
- 权重区间计算逻辑错误:你当前的实现没有对元素权重做累加校验,每个元素的判断阈值
100 - element.weight完全独立,没有划分互不重叠的概率区间,遍历元素时后面的元素会覆盖前面的赋值,最终概率分布完全不符合预期。 - 初始值设置不合理:
num初始值固定为0,当所有元素的判断条件都未触发时会直接返回0,不会抛出异常,进一步掩盖了逻辑缺陷。
拿你给出的4个权重均为25的Eyes图层举例,所有元素的判断条件都是randElementNum >= 75,最终只会出现两种结果:
- 随机数小于75时,所有判断条件都不满足,num保持初始值0
- 随机数大于等于75时,最后一个元素(id=3)的判断触发,覆盖之前的赋值,num返回3
完全无法命中id为1、2的元素,和你遇到的「仅返回少量值」的现象完全吻合。
修复方案
修改createDna函数中权重匹配的逻辑,改用累加权重区间匹配的方式,匹配到对应元素后直接终止遍历,避免后续元素覆盖赋值:
const createDna = (_races, _race) => { let randNum = []; _races[_race].layers.forEach((layer) => { let randElementNum = Math.floor(Math.random() * 100) + 1; let num = 0; let accumulatedWeight = 0; // 遍历元素时累加权重,判断随机数落在哪个区间 for (let i = 0; i < layer.elements.length; i++) { const element = layer.elements[i]; accumulatedWeight += element.weight; if (randElementNum <= accumulatedWeight) { num = element.id; // 匹配到后直接终止循环,避免后续覆盖 break; } } randNum.push(num); }); return randNum; };
调整后4个权重25的元素对应的区间分别是:
- id0:1~25
- id1:26~50
- id2:51~75
- id3:76~100
所有元素的命中概率和配置的权重完全一致,不会出现无法遍历全部可选值的问题。
内容的提问来源于stack exchange,提问作者Michael Downey
相关产品推荐
相关产品推荐

