You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

求助:如何按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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.23 12:27:38