calculatePercentage = function (valueList,idx,precision = 2){
// 判断是否为空
if(!valueList[idx]) {
return 0
}
// 求和
var sum = valueList.reduce(function(acc,val) {
return acc + (isNaN(val) ? 0 : val);
},0)
if(sum === 0) {
return 0;
}
// 10的二次幂是100,用于计算精度。
var digits = Math.pow(10,precision);//扩大比例100
var votesPerQuota = valueList.map(function(val) {
return ((isNaN(val) ? 0 : val)/sum) *digits * 100;
})// 总数,扩大比例以为的总数要扩大
var targetSeats = digits * 100;// 再向下取值,组成数组
var seats = votesPerQuota.map(function(votes) {
return Math.floor(votes);
})// 再新计算合计,用域判断与总数量是否相同,相同则占比会100%
var currentSum = seats.reduce(function(acc,val) {
return acc + val;
},0)// 余数部分的数组:原先数组减去向下取值的数组,得到余数部分的数组
var remainder = votesPerQuota.map(function(votes,idx) {
return votes - seats [idx];
})// 给最大最大的余数加1,凑个占比100%
while (currentSum < targetSeats) {
// 找到下一个最大的余数,给其加1
var max = Number.NEGATIVE_INFINITY;
var maxId = null;
for(var i = 0; len = remainder.length; i < len; ++i) {
if(remainder[i] > max){
max = remainder[i];
maxId = i;
}
}// 对最大项余数加1
++seats [maxId];// 已经增加最大余数加1,则下次判断就可以不需要在判断这个余额数
remainder[maxId] = 0;// 总的也要加1,为了判断总数是否相同,跳出循环
++currentSum;
}// 这时候的seats就会总数占比100%
return (seats[idx] / digits).toFixed(precision) == 100.00 ? 100 : (seats[idx] / digits).toFixed(precision)
}
// 使用
let arr = []//数据接收
arr.forEatch((item,index) =>{
const num = calculatePercentage(arr.map(typeItem => typeItem.num), index, 2)
})
计算百分比
于 2024-08-23 08:57:55 首次发布