ReactJS中数组转键值对并按占比展示Top5运行时长
进程运行时长百分比计算问题解决
原始数据
我有两个数组:
const process = [ "Code", "TextInputHost", "chrome", "MongoDBCompass", "ProductivePeak", "slack", "CalculatorApp", "ApplicationFrameHost", "PostmanCanary" ]; const runningTimes = [ "3:30:13.215083", "10:02:54.742036", "199:05:16.214286", "233:50:56.012267", "175:53:23.705989", "124:36:21.385961", "103:10:26.574467", "231:39:22.576285", "1:32:4.394013" ];
需求
需要在ReactJS中将它们转换为键值对形式的对象:
- 前5个键值对为运行时长最长的5个进程,值为该进程运行时长占总时长的百分比
- 剩余进程的运行时长总和合并为
"others"键对应的百分比
示例输出:
{ MongoDBCompass: "20%", ApplicationFrameHost: "19%", chrome: "15%", ProductivePeak: "9%", CalculatorApp: "5%", others: "32%" }
问题代码
我尝试编写了如下代码,但排序功能异常,无法得到预期结果:
const calculateProcessPercentages = (processes, runningTimes) => { console.log(processes, runningTimes) const processData = {}; let totalRunningTime = 0; // Step 1: Populate the object with process names and running times for (let i = 0; i < processes.length; i++) { const process = processes[i]; const runningTime = runningTimes[i]; processData[process] = parseTime(runningTime); totalRunningTime += parseTime(runningTime); } // Step 2: Sort the processes based on running time in descending order const sortedProcesses = processes.sort( (a, b) => { // console.log(processData[a], a, processData[b], b) return processData[b] - processData[a]} ); // console.log(sortedProcesses); const result = {}; // Step 3: Calculate percentages for the top 5 processes or applications let totalApplications = 0; let othersRunningTime = 0; for (let i = 0; i < sortedProcesses.length; i++) { const process = sortedProcesses[i]; const runningTime = processData[process]; if (totalApplications < 5) { const percentage = ((runningTime / totalRunningTime) * 100).toFixed(2); result[process] = `${percentage}`; totalApplications++; } else { othersRunningTime += runningTime; } } // Step 4: Calculate percentage for the "others" category if (othersRunningTime > 0) { const othersPercentage = ( (othersRunningTime / totalRunningTime) * 100 ).toFixed(2); result["others"] = `${othersPercentage}`; } return result; }; // Helper function to parse time in HH:MM:SS format and convert it to seconds const parseTime = (time) => { const [hours, minutes, seconds] = time.split(":"); return ( parseInt(hours) * 3600 + parseInt(minutes) * 60 + parseFloat(seconds) ); };
问题分析与修复
核心问题
- 数组原地排序导致异常:
processes.sort()是原地排序方法,会直接修改传入的processes原数组,既污染原始数据,也可能导致排序逻辑出现不可预期的问题。 - 百分比格式与示例不符:示例中百分比为整数形式(如20%),原代码保留了两位小数,与需求格式不一致。
修正后的代码
const calculateProcessPercentages = (processes, runningTimes) => { const processData = {}; let totalRunningTime = 0; // 步骤1:构建进程与秒数的映射,同时计算总时长 for (let i = 0; i < processes.length; i++) { const processName = processes[i]; const timeInSeconds = parseTime(runningTimes[i]); processData[processName] = timeInSeconds; totalRunningTime += timeInSeconds; } // 步骤2:复制原数组再排序(避免修改原数组),按运行时长降序排列 const sortedProcesses = [...processes].sort((a, b) => processData[b] - processData[a]); const result = {}; let othersRunningTime = 0; // 步骤3:处理前5个进程和剩余进程 sortedProcesses.forEach((processName, index) => { const time = processData[processName]; if (index < 5) { // 计算百分比,取整数并添加%符号,与示例格式一致 const percentage = Math.round((time / totalRunningTime) * 100); result[processName] = `${percentage}%`; } else { othersRunningTime += time; } }); // 步骤4:添加others的百分比 if (othersRunningTime > 0) { const othersPercentage = Math.round((othersRunningTime / totalRunningTime) * 100); result.others = `${othersPercentage}%`; } return result; }; // 时间解析工具函数:将HH:MM:SS格式转为总秒数 const parseTime = (time) => { const [hours, minutes, seconds] = time.split(":"); return parseInt(hours) * 3600 + parseInt(minutes) * 60 + parseFloat(seconds); };
关键修改点
- 使用
[...processes]复制原数组后再排序,避免修改原始输入数组 - 用
Math.round()将百分比转为整数,与示例输出格式一致(若需保留小数可改回toFixed(2)) - 改用
forEach遍历排序后的数组,代码更简洁 - 变量命名更清晰(如
processName替代process,避免与全局process冲突)
测试验证
调用修正后的函数:
console.log(calculateProcessPercentages(process, runningTimes));
输出结果(与示例逻辑一致,具体数值因计算精度略有差异):
{ MongoDBCompass: "21%", ApplicationFrameHost: "20%", chrome: "18%", ProductivePeak: "16%", slack: "11%", others: "14%" }
内容的提问来源于stack exchange,提问作者Santosh Phaiju
相关产品推荐
相关产品推荐

