JS使用map/filter/reduce实现数组按占比筛选合并功能
实现方案
补全现有代码的缺失逻辑
你已完成的代码不需要改动,只需要追加低占比项的聚合逻辑即可,步骤如下:
- 筛选出所有占比不满足阈值的项
- 累加这些项的
qty和percentage字段,生成others汇总项 - 若低占比项总数量大于0,将汇总项追加到结果数组末尾
对应追加的代码片段:
// 聚合低占比项数据 const othersAgg = rawData .filter(el => el.percentage <= 10) .reduce((sumNode, cur) => { sumNode.qty += cur.qty; sumNode.percentage += cur.percentage; return sumNode; }, { idCompany: null, name: 'others', qty: 0, percentage: 0 }); // 存在低占比数据时才追加others项 if (othersAgg.qty > 0) { // 可按需调整百分比保留的小数位数 othersAgg.percentage = Number(othersAgg.percentage.toFixed(3)); consolidateCompanies.push(othersAgg); }
更简洁的性能优化写法
上述写法会多次遍历数组,你可以用单次reduce完成全流程计算,减少遍历次数,逻辑更聚合,也方便后续调整阈值:
const data = [/* 你的原始数据 */]; const THRESHOLD = 10; // 占比阈值,可灵活修改 // 第一步计算总qty const totalQty = data.reduce((sum, item) => sum + item.qty, 0); // 单次遍历拆分达标项、聚合others项 const { finalList, others } = data.reduce((acc, item) => { const percentage = (item.qty / totalQty) * 100; const formattedItem = { idCompany: item.id, name: item.company, qty: item.qty, percentage }; if (percentage > THRESHOLD) { acc.finalList.push(formattedItem); } else { acc.others.qty += item.qty; acc.others.percentage += percentage; } return acc; }, { finalList: [], others: { idCompany: null, name: 'others', qty: 0, percentage: 0 } }); // 存在未达标数据时追加汇总项 if (others.qty > 0) { others.percentage = Number(others.percentage.toFixed(3)); finalList.push(others); } console.log(finalList);
注意点
- 直接累加低占比项的占比,比用100减去达标项总占比的方式,能更好规避JS浮点数计算误差
- 示例数据运行后,输出的others项
qty为8,占比约为10.39%,和你期望的结果完全一致 - 百分比的小数精度可以通过修改
toFixed()的入参自行调整
内容的提问来源于stack exchange,提问作者sineverba
相关产品推荐
相关产品推荐

