基于sID和nID合并记录count字段的问题求助
合并相同sId和nId记录的count数据问题
需求:基于共同的sId和nId合并记录中的count数据,同一sId和nId的记录分别包含status.count.mr、status.count.ar等数值字段,需将这类记录合并为单个JSON对象,保留各数值字段的有效取值。
原始数据
const records = [ {division: {name: "AAA", sId: 1, nId: 111}, status: {dates: {nDate: "02-20", dDate: "03-20"}, count: {emr: 0, mr: 0, ar: 0, totalAR: 0, totalEMR: 10, totalMR: 0}}}, {division: {name: "AAA", sId: 1, nId: 222}, status: {dates: {nDate: "02-19", dDate: "03-20"}, count: {emr: 0, mr: 0, ar: 0, totalAR: 0, totalEMR: 10, totalMR: 0}}}, {division: {name: "BBB", sId: 2, nId: 111}, status: {dates: {nDate: "02-20", dDate: "03-20"}, count: {emr: 0, mr: 5, ar: 0, totalAR: 0, totalEMR: 0, totalMR: 9}}}, {division: {name: "BBB", sId: 2, nId: 111}, status: {dates: {nDate: "02-20", dDate: "03-20"}, count: {emr: 0, mr: 0, ar: 2, totalAR: 7, totalEMR: 0, totalMR: 0}}}, {division: {name: "BBB", sId: 2, nId: 222}, status: {dates: {nDate: "02-19", dDate: "03-20"}, count: {emr: 0, mr: 3, ar: 0, totalAR: 0, totalEMR: 0, totalMR: 9}}}, {division: {name: "BBB", sId: 2, nId: 222}, status: {dates: {nDate: "02-19", dDate: "03-20"}, count: {emr: 0, mr: 0, ar: 4, totalAR: 7, totalEMR: 0, totalMR: 0}}} ]
尝试的解决方案
const mergedMap = new Map(); for (const record of records) { const { sId, nId } = record.division; const existingRecord = mergedMap.get(`${sId}-${nId}`); if (existingRecord) { mergedMap.set(`${sId}-${nId}`, { division: existingRecord.division, status: {...existingRecord.status, count: {...existingRecord.status.count, ...record.status.count}, dates: {...existingRecord.status.dates, ...record.status.dates}, }, }); } else { mergedMap.set(`${sId}-${nId}`, record); } } const mergedData = Array.from(mergedMap.values());
期望结果
const mergedData = [ {division: {name: "AAA", sId: 1, nId: 111}, status: {dates: {...}, count: {emr: 0, mr: 0, ar: 0, totalAR: 0, totalEMR: 10, totalMR: 0}}}, {division: {name: "AAA", sId: 1, nId: 222}, status: {dates: {...}, count: {emr: 0, mr: 0, ar: 0, totalAR: 0, totalEMR: 10, totalMR: 0}}}, {division: {name: "BBB", sId: 2, nId: 111}, status: {dates: {...}, count: {emr: 0, mr: 5, ar: 2, totalAR: 7, totalEMR: 0, totalMR: 9}}}, {division: {name: "BBB", sId: 2, nId: 222}, status: {dates: {...}, count: {emr: 0, mr: 3, ar: 4, totalAR: 7, totalEMR: 0, totalMR: 9}}} ]
实际结果
const mergedData = [ {division: {name: "AAA", sId: 1, nId: 111}, status: {dates: {...}, count: {emr: 0, mr: 0, ar: 0, totalAR: 0, totalEMR: 10, totalMR: 0}}}, {division: {name: "AAA", sId: 1, nId: 222}, status: {dates: {...}, count: {emr: 0, mr: 0, ar: 0, totalAR: 0, totalEMR: 10, totalMR: 0}}}, {division: {name: "BBB", sId: 2, nId: 111}, status: {dates: {...}, count: {emr: 0, mr: 0, ar: 2, totalAR: 7, totalEMR: 0, totalMR: 0}}}, {division: {name: "BBB", sId: 2, nId: 222}, status: {dates: {...}, count: {emr: 0, mr: 0, ar: 4, totalAR: 7, totalEMR: 0, totalMR: 0}}} ]
问题原因与修正方案
问题原因
原代码使用对象扩展运算符...直接合并count对象,当第二个记录的字段值为0时,会覆盖第一个记录的非0值(比如mr:5会被后续的mr:0覆盖),导致有效数值丢失。
修正后的代码
const mergedMap = new Map(); for (const record of records) { const { sId, nId } = record.division; const key = `${sId}-${nId}`; const existingRecord = mergedMap.get(key); if (existingRecord) { // 合并count字段,累加数值 const mergedCount = {...existingRecord.status.count}; Object.keys(record.status.count).forEach(countKey => { mergedCount[countKey] = mergedCount[countKey] + record.status.count[countKey]; }); mergedMap.set(key, { division: existingRecord.division, status: { ...existingRecord.status, count: mergedCount, dates: {...existingRecord.status.dates, ...record.status.dates} } }); } else { mergedMap.set(key, {...record}); // 浅拷贝避免修改原数据 } } const mergedData = Array.from(mergedMap.values());
说明
- 遍历
count的所有键,对每个数值字段进行累加,而非直接覆盖,确保非0值不会被后续的0值覆盖。 - 对原始记录进行浅拷贝,避免后续修改影响原数据。
dates字段保留原合并逻辑,若同一组记录的dates存在差异,会用后续记录的值覆盖,若需保留所有日期可按需调整。
内容的提问来源于stack exchange,提问作者TMA
相关产品推荐
相关产品推荐

