求助:如何按fileName统计matchingStatus的匹配占比(JS)
问题描述
已有一段claimData JSON数据,通过reduce按fileName字段分组得到了groupedClaimFileMap,现在需要统计每个fileName分组内matchingStatus为MATCHED的占比,但尝试的reduce代码出现统计结果嵌套异常,求正确实现语法。
示例JSON数据:
const claimData = [ {"id":1, "matchingStatus":"MATCHED", "fileName": "abcd.pdf", "amount":123.45}, {"id":2, "matchingStatus":"MATCHED", "fileName": "efg12.pdf", "amount":234.45}, {"id":3, "matchingStatus":"UNMATCHED", "fileName": "mnbv.pdf", "amount":100.00}, {"id":4, "matchingStatus":"MATCHED", "fileName": "kjhg.pdf", "amount":345.45}, {"id":5, "matchingStatus":"UNMATCHED", "fileName": "efg12.pdf", "amount":555.45}, {"id":6, "matchingStatus":"MATCHED", "fileName": "efg12.pdf", "amount":200.45} ];
已实现的分组代码:
this.groupedClaimFileMap = claimData.reduce( (entryMap, e) => entryMap.set(e.fileName, [...(entryMap.get(e.fileName) || []), e]), new Map() );
尝试的错误统计代码:
this.groupedSummary = claimData.reduce( (entryMap, e) => entryMap.set(e.fileName, [ [...(entryMap.get(e.fileName) || []), e], entryMap[e.matchingStatus] ? ++entryMap[e.matchingStatus] : (entryMap[e.matchingStatus] = 1), entryMap, ]), new Map() );
解决方案
方案一:基于已有分组结果统计
利用已生成的groupedClaimFileMap,直接遍历计算每个文件的匹配占比,逻辑更直观:
this.groupedSummary = new Map(); this.groupedClaimFileMap.forEach((items, fileName) => { const total = items.length; const matchedCount = items.filter(item => item.matchingStatus === 'MATCHED').length; // 处理总数为0的边界情况,避免除零错误 const matchedRatio = total > 0 ? (matchedCount / total).toFixed(2) : 0; this.groupedSummary.set(fileName, { total, matchedCount, matchedRatio }); });
方案二:一次Reduce完成分组+统计
如果不想先分组再二次遍历,可以用一次reduce直接生成统计结果,减少性能开销:
this.groupedSummary = claimData.reduce((summaryMap, item) => { const fileName = item.fileName; // 初始化当前文件的统计数据,无则创建默认结构 const currentStats = summaryMap.get(fileName) || { total: 0, matchedCount: 0 }; currentStats.total++; if (item.matchingStatus === 'MATCHED') { currentStats.matchedCount++; } // 实时计算占比,保留两位小数 currentStats.matchedRatio = (currentStats.matchedCount / currentStats.total).toFixed(2); return summaryMap.set(fileName, currentStats); }, new Map());
结果说明
两种方案最终生成的groupedSummary结构一致,以示例数据为例,结果如下:
Map(4) { 'abcd.pdf' => { total: 1, matchedCount: 1, matchedRatio: '1.00' }, 'efg12.pdf' => { total: 3, matchedCount: 2, matchedRatio: '0.67' }, 'mnbv.pdf' => { total: 1, matchedCount: 0, matchedRatio: '0.00' }, 'kjhg.pdf' => { total: 1, matchedCount: 1, matchedRatio: '1.00' } }
错误代码问题分析
你之前的代码存在以下问题:
- 将整个
entryMap作为值的一部分存入,导致嵌套引用异常 - 直接修改
entryMap上的matchingStatus属性,混淆了Map的键值结构 - 用数组存储统计数据,结构混乱,不符合统计需求
内容的提问来源于stack exchange,提问作者annaM
相关产品推荐
相关产品推荐

