思路:计算区间内每一个元素的概率,根据每一个元素的概率得到一个0-100之间的区间,再生成一个随机数落在这个区间,返回所对应的键值即随机数。
class GLRandom {
/**
* 构造函数
* @param {number} min 最小整数值
* @param {number} max 最大整数值
* @param {Map} percentage 概率数 [值,百分比]
*/
constructor(eles, percentage = new Map()) {
this.eles = eles;
this.MATH_RANGE = 100; // 分成100份
this.percentage = percentage; //首先给每一个数都设置了概率
this.range();
}
get percentage() {
if (!this._percentage) {
this._percentage = new Map();
}
return this._percentage;
}
/**
* 分配比例
* @param {Map} map 设置 值-百分比
*/
set percentage(map) {
let result = Array.from(map.values()).reduce((p, v, a) => {
return p - v;
}, 1);
for (let i = 0; i < this.eles.length; i++) {
let item = this.eles[i];
if (map.has(item)) {
this.percentage.set(item, map.get(item)); //有的就直接设置概率
} else {
this.percentage.set(item, result / (this.eles.length - map.size)); //没有的均分概率
}
}
}
/**
* 根据比例生成取值范围
*/
range() {
let [start, random, keys] = [
0,
this.MATH_RANGE,
Array.from(this.percentage.keys()),
];
for (let i = 0; i < keys.length; i++) {
let temp = this.percentage.get(keys[i]);
this.percentage.set(keys[i], [start, (start += temp * random)]);
}
}
/**
* 生成随机数
*/
create() {
let num = Math.random() * this.MATH_RANGE;
for (let data of this.percentage.entries()) {
//通过随机数落在一个区间,然后获取到它对应的key
if (num >= data[1][0] && num < data[1][1]) {
return data[0];
}
}
return null;
}
}
// 随机数范围 :40~900
let random = new GLRandom(
["40", "46", "42", "50", "57", "48", "92", "83", "43"],
new Map([
["40", 0.2], // 调整值为41的数值,概率为20%
["46", 0.5], // 调整值为46的数值,概率为50%
])
);
random.create();