计算百分比

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)
})
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值