当前位置: 首页 > news >正文

最大余额法,解决百分比计算相加不等于100%(扇形/饼图百分比使用的此算法)

在开发项目的过程中有时候需要进行计算百分比,例如计算饼状图百分比。有时候在计算的过程中常规四舍五入计算会发生所有计算的值相加不等于100%的情况
这是 get_percent_value 函数的 JavaScript 版本:

/*** 最大余额法,解决百分比计算相加不等于100%(扇形/饼图百分比使用的此算法)* @param {Array} valueList 二维数组 [{value: 1}, {value: 2}, {value: 3}]* @param {string} contKey 要统计的字段* @param {number} precision 精度(默认为2保留百分比格式的两位小数)* @param {string} percentKey 百分比键名* @param {boolean} format 是否需要返回格式化后百分比格式,false则返回小数* @return {Array}*/
function getPercentValue(valueList, contKey, precision = 2, percentKey = 'percent', format = true) {if (valueList.length === 0) {return [];}// 求和const sum = valueList.reduce((acc, item) => acc + item[contKey], 0);// 如果总和为0,直接返回if (sum === 0) {return valueList.map(item => ({...item,[percentKey]: format ? '0%' : 0}));}// 计算精度const digits = Math.pow(10, precision);let currentSum = 0;let remainder = [];// 计算每个项目的整数和余数部分valueList.forEach((item, index) => {const votesPerQuota = (item[contKey] / sum) * digits * 100;const integerPart = Math.floor(votesPerQuota);valueList[index].integer = integerPart;remainder[index] = votesPerQuota - integerPart;currentSum += integerPart;});const targetSeats = digits * 100;// 找到最大余数并加1,直到总数达到目标while (currentSum < targetSeats) {const maxIndex = remainder.indexOf(Math.max(...remainder));valueList[maxIndex].integer++;remainder[maxIndex] = -1; // 确保该余数不会再被选中currentSum++;}// 生成最终的百分比值valueList.forEach(item => {item[percentKey] = (item.integer / targetSeats).toFixed(precision + 2);if (format) {item[percentKey] = (parseFloat(item[percentKey]) * 100).toFixed(precision) + '%';}delete item.integer;});return valueList;
}// 使用示例
const data = [{ value: 3 },{ value: 3 },{ value: 3 }
];const rateData = getPercentValue(data, 'value', 2, 'percent', false);
console.log(rateData);

说明:

  • reduce 用于求和。
  • Math.floor 用于获取整数部分。
  • Math.maxindexOf 用于找到最大余数的位置。
  • toFixed 保留指定的小数位数。

你可以通过 getPercentValue 函数来计算各项的百分比,并决定是否返回格式化的百分比形式。

http://www.lryc.cn/news/438118.html

相关文章:

  • 哈希表简单介绍
  • kafka 之 本地部署单机版
  • 开发一款通过蓝牙连接控制水电表的微信小程序
  • 力扣14.最长公共前缀
  • 你也喜欢“钓鱼“吗?
  • druid jdbc 执行 sql 输出 开销耗时
  • C++如何处理内存碎片问题
  • FreeRTOS常用API接口函数
  • DesignPattern设计模式
  • 3.ChatGPT在教育领域的应用:教学辅助与案例分享(3/10)
  • Kafka+PostgreSql,构建一个总线服务
  • 电脑怎么录屏?四款录屏工具分享
  • Java代码审计篇 | ofcms系统审计思路讲解 - 篇4 | XXE漏洞审计
  • Leetcode 每日一题:Word Ladder
  • c++ 编辑器 和 编译器 的详细解释
  • 计算机视觉(二)—— MDPI特刊推荐
  • 交叉编译工具链的安装及带wiringPi库的交叉编译实现
  • java: 程序包org.junit.jupiter.api不存在
  • 代码随想录刷题day32丨动态规划理论基础,509. 斐波那契数, 70. 爬楼梯, 746. 使用最小花费爬楼梯
  • 为什么矩阵特征值之和等于主对角线元素之和,特征值乘积等于行列式值
  • 学生学籍管理系统可行性分析报告
  • C#排序算法新境界:深度剖析与高效实现基数排序
  • 玩机搞机-----如何简单的使用ADB指令来卸载和冻结系统应用 无需root权限 详细操作图示教程
  • 如何通过 Apache Camel 将数据导入 Elasticsearch
  • 打造民国风格炫酷个人网页:用HTML和CSS3传递民国风韵
  • 豆包MarsCode编程助手:产品功能解析与应用场景探索!
  • 爬虫全网抓取
  • 【计算机组成原理】详细解读带符号整数在计算机中的运算
  • vue3常见的bug 修复bug
  • C++课程笔记 类和对象