当前位置:首页 > JavaScript

js实现一个权重抽奖

2026-03-02 00:56:55JavaScript

js实现一个权重抽奖

权重抽奖实现方法

权重抽奖的核心是根据不同奖项的权重值计算概率,并通过随机数选择对应的奖项。以下是基于JavaScript的实现方法:

js实现一个权重抽奖

方法一:使用累积概率区间

function weightedDraw(prizes) {
  // 计算总权重
  const totalWeight = prizes.reduce((sum, prize) => sum + prize.weight, 0);

  // 生成随机数
  const random = Math.random() * totalWeight;

  // 遍历奖品计算累积权重
  let currentWeight = 0;
  for (const prize of prizes) {
    currentWeight += prize.weight;
    if (random <= currentWeight) {
      return prize;
    }
  }

  // 默认返回最后一个
  return prizes[prizes.length - 1];
}

// 使用示例
const prizes = [
  { name: "一等奖", weight: 1 },
  { name: "二等奖", weight: 3 },
  { name: "三等奖", weight: 6 }
];
const result = weightedDraw(prizes);
console.log(result.name);

方法二:预计算概率表(适合高频调用)

class WeightedRandom {
  constructor(items) {
    this.total = items.reduce((sum, item) => sum + item.weight, 0);
    this.table = items.map(item => ({
      value: item.value,
      threshold: item.weight / this.total
    }));
    // 计算累积概率
    let accum = 0;
    this.table = this.table.map(item => {
      accum += item.threshold;
      return { ...item, accum };
    });
  }

  draw() {
    const random = Math.random();
    return this.table.find(item => random <= item.accum)?.value;
  }
}

// 使用示例
const wr = new WeightedRandom([
  { value: "黄金", weight: 10 },
  { value: "白银", weight: 30 },
  { value: "青铜", weight: 60 }
]);
console.log(wr.draw());

方法三:ES6优化版本

const weightedRandom = (items) => {
  const total = items.reduce((acc, { weight }) => acc + weight, 0);
  const rand = Math.random() * total;
  let sum = 0;

  return items.find(({ weight }) => (sum += weight) >= rand)?.item;
};

// 使用示例
const items = [
  { item: "iPhone", weight: 5 },
  { item: "iPad", weight: 15 },
  { item: "优惠券", weight: 80 }
];
console.log(weightedRandom(items));

关键点说明

  • 权重值可以是任意正数,不需要总和为1或100
  • 权重越大被抽中的概率越高
  • 算法时间复杂度为O(n),对于大量选项可考虑二分查找优化
  • 随机数生成使用Math.random(),如需更安全随机数可使用crypto.getRandomValues()

实际应用扩展

对于需要展示概率分布的场景,可先计算各奖项的实际概率:

function calculateProbabilities(prizes) {
  const total = prizes.reduce((sum, p) => sum + p.weight, 0);
  return prizes.map(p => ({
    ...p,
    probability: (p.weight / total * 100).toFixed(2) + '%'
  }));
}

以上实现可根据具体需求调整,如添加重复抽奖限制、奖品库存控制等功能。

标签: 权重js
分享给朋友:

相关文章

js实现预览

js实现预览

文件上传预览实现 使用JavaScript实现文件上传预览功能,可以通过FileReader对象读取文件内容并显示预览。以下代码支持图片、文本和PDF文件的预览: // HTML部分需要包含…

js实现文字滚动

js实现文字滚动

实现文字滚动的几种方法 使用CSS动画实现滚动 通过CSS的@keyframes和transform属性可以实现平滑的文字滚动效果。 <style> .scroll-text { w…

js分页实现

js分页实现

分页的基本原理 分页的核心是通过计算当前页码和数据偏移量,从服务器或本地数据中截取对应范围的数据进行展示。通常需要以下参数:当前页码(currentPage)、每页条数(pageSize)、总数据量(…

js实现删除

js实现删除

使用 splice 方法删除数组元素 splice 方法可以删除数组中的元素,并返回被删除的元素。它接受两个参数:起始索引和要删除的元素数量。 const array = [1, 2, 3, 4…

js 实现图片轮播

js 实现图片轮播

基础实现方案 使用HTML、CSS和JavaScript创建一个简单的图片轮播。HTML部分定义轮播容器和图片,CSS负责样式布局,JavaScript处理轮播逻辑。 <div class="…

js 实现验证码

js 实现验证码

实现验证码的 JavaScript 方法 生成随机验证码 验证码通常由随机字符(数字、字母或混合)组成。以下代码生成一个 6 位随机验证码(数字和字母混合): function generateCa…