前言
近期需要为平安普惠公众号开发一个抽奖发红包的需求,在抽奖页面的下方需要滚动展示用户中奖信息,如下图所示
由于活动参与的人数多,并发量高,为了减轻服务器的访问压力,决定前端用js算法来随机生成用户中奖记录。
一、抽奖需求
1、抽奖金额权重
- 1~200元,中奖概率为20%,记为一等奖
- 0.5~1元,中奖概率为20%,记为二等奖
- 0.3~0.5元,中奖概率为60%,记为三等奖
2、金额要取奖项范围的随机值
- 假如用户中的是一等奖,则金额为1~200元的随机值,如23.89元
- 假如用户中的是二等奖,则金额为0.5~1元的随机值,如0.8元
- 假如用户中的是三等奖,则金额为0.3~0.5的随机值,如0.34元
二、算法实现
1、计算用户中了几等奖
- 抽奖方法,接收奖项参数
// 抽奖方法
function Draw(prizes) {
var prizeList = [] //按照权重分解后的奖品数组
prizes.map(function(item) {
prizeList.push({
name : item.name,
value : item.key
})
for (var i = 0; i < item.probability; i++) {
prizeList.push({
name : item.name,
value : item.key
})
}
});
prizeList = reset(prizeList);
// 范围随机数
function randomFrom(lowerValue, upperValue) {
return Math.floor(Math.random() * (upperValue - lowerValue + 1)
+ lowerValue);
}
;
// 随机打乱数组
function reset(arr) {
var eachArr = arr.concat([])
var lastArr = []
function deepEach(deepArr) {
if (deepArr.length) {
var randomIndex = randomFrom(0, eachArr.length - 1)
lastArr.push(eachArr[randomIndex])
eachArr.splice(randomIndex, 1)
deepEach(eachArr)
}
}
deepEach(eachArr)
return lastArr
}
this.getResult = function() {
var random = randomFrom(0, prizeList.length - 1);
return prizeList[random]
}
}
- 奖项数据结构
// 奖项和概率数据结构,probability 为中奖概率,可以根据实际需求修改
var model = [ {
name : '一等奖',
key : 'level1',
probability : 20,
}, {
name : '二等奖',
key : 'level2',
probability : 20,
}, {
name : '三等奖',
key : 'level3',
probability : 60,
} ]
2、生成相应奖项的随机金额
//生成从minNum到maxNum的随机数
function randomNum(maxNum, minNum, decimalNum) {
// 获取指定范围内的随机数, decimalNum指小数保留多少位
var max = 0,
min = 0;
minNum <= maxNum ? (min = minNum, max = maxNum) : (min = maxNum, max = minNum);
switch (arguments.length) {
case 1:
return Math.floor(Math.random() * (max + 1));
break;
case 2:
return Math.floor(Math.random() * (max - min + 1) + min);
break;
case 3:
return (Math.random() * (max - min) + min).toFixed(decimalNum);
break;
default:
return Math.random();
break;
}
}
3、抽奖
window.onload = function() {
// 创建抽奖对象
var draw = new Draw(model);
// 抽奖100次
var total = 100;
// 中一等奖个数
var first = 0;
// 中二等奖个数
var second = 0;
// 中三等奖个数
var third = 0;
// 中奖结果
var results = new Array(total);
for(var i=0;i<total;i++){
// 获取中了几等奖
var drawResult = draw.getResult();
// 生成相应奖项的随机金额
var value = 0;
if (drawResult.name == '一等奖') {
// 1-200,两位小数
value = randomNum(1,200,2);
first++;
} else if (drawResult.name == '二等奖') {
// 0.5-1,两位小数
value = randomNum(0.5,1,2);
second++;
} else if (drawResult.name == '三等奖') {
// 0.3-0.5,两位小数
value = randomNum(0.3,0.5,2);
third++;
}
results[i] = value;
}
console.log("results:" + results);
console.log("total:" + total);
console.log("first:" + first + ",比例:" + (first / total));
console.log("second:" + second + ",比例:" + (second / total));
console.log("third:" + third + ",比例:" + (third / total));
};
抽奖100次结果如下
写在最后
虽然本文通过js实现了随机抽奖算法,但仅仅是用于伪数据展示,如果项目要求数据必须真实,还是需要通过后台实现。