JavaScript优雅高效生成带概率权重的指定大小对象数组方法
按概率随机生成对象数组的高效实现方案
要摆脱冗余的多条件判断、同时提升性能,前缀和+二分查找是更优的实现思路,尤其适合概率配置较多的场景。
核心逻辑
- 将每个对象的概率转换为权重区间:以概率总和100(对应100%)为基准,通过前缀和构建每个对象对应的数值范围(比如A概率5对应1-5,B概率10对应6-15,以此类推)。
- 生成1-100的随机数,通过二分查找快速定位随机数所属区间,从而选中对应对象。
代码示例(JavaScript)
// 定义带概率的源对象数组 const sourceObjects = [ { id: 'obj1', prob: 5 }, // 5% { id: 'obj2', prob: 10 }, // 10% { id: 'obj3', prob: 20 }, // 20% { id: 'obj4', prob: 65 } // 65% ]; // 预处理:计算前缀和数组,绑定对应对象 const prefixSum = []; let currentSum = 0; for (const obj of sourceObjects) { currentSum += obj.prob; prefixSum.push({ sum: currentSum, obj }); } // 根据随机数获取对应对象的工具函数 function getRandomObject() { const randomNum = Math.floor(Math.random() * 100) + 1; // 生成1-100的随机数 // 二分查找定位区间 let left = 0; let right = prefixSum.length - 1; while (left < right) { const mid = Math.floor((left + right) / 2); if (prefixSum[mid].sum >= randomNum) { right = mid; } else { left = mid + 1; } } return prefixSum[left].obj; } // 生成包含100个对象的结果数组 const resultArray = Array.from({ length: 100 }, getRandomObject); console.log(resultArray);
方案优势
- 可维护性强:新增或修改对象概率时,只需调整
sourceObjects数组,无需修改判断逻辑。 - 性能更高效:预处理仅需O(n)时间,每次查找是O(logn)复杂度,远优于逐个条件判断的O(n)查找,源对象数量越多优势越明显。
- 代码更简洁:彻底避免冗长的
if-else或switch嵌套,逻辑清晰直观。
内容的提问来源于stack exchange,提问作者Tay Baye
相关产品推荐
相关产品推荐

