基于原生JavaScript的自定义数据聚合问题求助
数据聚合逻辑代码修正
初始数据
const data = [ { date: '2023-11-01', type: 'A', casualties: 10, state: 'NY', country: 'USA', site: 'hash1' }, { date: '2023-11-01', type: 'B', casualties: 5, state: 'NY', country: 'USA', site: 'hash2' }, { date: '2023-11-02', type: 'A', casualties: 15, state: 'NY', country: 'USA', site: 'hash3' }, { date: '2023-11-01', type: 'C', casualties: 20, state: 'NY', country: 'USA', site: 'hash4' }, { date: '2023-11-02', type: 'B', casualties: 8, state: 'NY', country: 'USA', site: 'hash5' }, { date: '2023-11-03', type: 'A', casualties: 25, state: 'NY', country: 'USA', site: 'hash6' }, { date: '2023-11-01', type: 'D', casualties: 12, state: 'NY', country: 'USA', site: 'hash7' }, ];
聚合规则
- 若某个
type的所有日期对应的casualties均大于等于设定阈值,需保留在results数组中; - 若某个
type的所有日期对应的casualties均低于阈值,且是唯一符合该条件的type,也需保留在results数组中; - 若有两个及以上
type的所有日期对应的casualties均低于阈值,则这些type不单独出现在results数组中,而是按日期汇总casualties,以type为other的形式展示; otherCasualties数组需包含所有满足“所有日期casualties均低于阈值”的type。
示例
阈值为9时
results = [ { date: '2023-11-01', type: 'A', casualties: 10, state: 'NY', country: 'USA' }, { date: '2023-11-01', type: 'B', casualties: 5, state: 'NY', country: 'USA' }, { date: '2023-11-02', type: 'A', casualties: 15, state: 'NY', country: 'USA' }, { date: '2023-11-01', type: 'C', casualties: 20, state: 'NY', country: 'USA' }, { date: '2023-11-02', type: 'B', casualties: 8, state: 'NY', country: 'USA' }, { date: '2023-11-03', type: 'A', casualties: 25, state: 'NY', country: 'USA' }, { date: '2023-11-01', type: 'D', casualties: 12, state: 'NY', country: 'USA' }, ];
此时otherCasualties = []
阈值为13时
results = [ { date: '2023-11-01', type: 'A', casualties: 10, state: 'NY', country: 'USA'}, { date: '2023-11-01', type: 'other', casualties: 17, state: 'NY', country: 'USA' }, { date: '2023-11-02', type: 'A', casualties: 15, state: 'NY', country: 'USA' }, { date: '2023-11-01', type: 'C', casualties: 20, state: 'NY', country: 'USA' }, { date: '2023-11-02', type: 'other', casualties: 8, state: 'NY', country: 'USA' }, { date: '2023-11-03', type: 'A', casualties: 25, state: 'NY', country: 'USA' }, ];
此时otherCasualties = ['B', 'D']
尝试的代码
function processCasualties(data, casualtiesThreshold) { const results = []; const otherCasualties = []; const groupedData = data.reduce((acc, item) => { const key = item.type; if (!acc[key]) { acc[key] = []; } acc[key].push(item); return acc; }, {}); const types = Object.keys(groupedData); types.forEach(type => { const typeData = groupedData[type]; const totalCasualties = typeData.reduce((acc, item) => acc + item.casualties, 0); const allDatesBelowThreshold = typeData.every(item => item.casualties < casualtiesThreshold); if (totalCasualties >= casualtiesThreshold || (allDatesBelowThreshold && types.length === 1)) { results.push(...typeData.map(item => ({ date: item.date, type: item.type, casualties: item.casualties, state: item.state, country: item.country, }))); } else if (allDatesBelowThreshold) { otherCasualties.push(type); } else { results.push(...typeData.map(item => ({ date: item.date, type: 'other', casualties: totalCasualties, state: item.state, country: item.country, }))); } }); return { results, otherCasualties }; } const casualtiesThreshold = 13; const { results, otherCasualties } = processCasualties(data, casualtiesThreshold); console.log(results); console.log(otherCasualties);
修正后的代码
function processCasualties(data, casualtiesThreshold) { const results = []; const otherCasualties = []; // 1. 按type分组数据 const groupedByType = data.reduce((acc, item) => { const key = item.type; if (!acc[key]) { acc[key] = []; } acc[key].push(item); return acc; }, {}); // 2. 筛选出所有满足"所有日期casualties均低于阈值"的type const belowThresholdTypes = Object.keys(groupedByType).filter(type => { return groupedByType[type].every(item => item.casualties < casualtiesThreshold); }); // 3. 填充otherCasualties数组 otherCasualties.push(...belowThresholdTypes); // 4. 判断是否需要聚合为other const needAggregate = belowThresholdTypes.length >= 2; const aggregatedOther = {}; // 处理各类type数据 Object.keys(groupedByType).forEach(type => { const typeData = groupedByType[type]; const isBelowThreshold = belowThresholdTypes.includes(type); if (!isBelowThreshold) { // 非阈值以下的type,直接保留原数据 results.push(...typeData.map(item => ({ date: item.date, type: item.type, casualties: item.casualties, state: item.state, country: item.country, }))); } else if (!needAggregate) { // 单个阈值以下的type,直接保留 results.push(...typeData.map(item => ({ date: item.date, type: item.type, casualties: item.casualties, state: item.state, country: item.country, }))); } else { // 需聚合的type,按日期累加casualties typeData.forEach(item => { const key = item.date; if (!aggregatedOther[key]) { aggregatedOther[key] = { date: item.date, type: 'other', casualties: 0, state: item.state, country: item.country, }; } aggregatedOther[key].casualties += item.casualties; }); } }); // 5. 将聚合后的other数据加入结果 if (needAggregate) { results.push(...Object.values(aggregatedOther)); } // 6. 按日期排序结果,与示例顺序一致 results.sort((a, b) => new Date(a.date) - new Date(b.date)); return { results, otherCasualties }; } // 测试用例 const data = [ { date: '2023-11-01', type: 'A', casualties: 10, state: 'NY', country: 'USA', site: 'hash1' }, { date: '2023-11-01', type: 'B', casualties: 5, state: 'NY', country: 'USA', site: 'hash2' }, { date: '2023-11-02', type: 'A', casualties: 15, state: 'NY', country: 'USA', site: 'hash3' }, { date: '2023-11-01', type: 'C', casualties: 20, state: 'NY', country: 'USA', site: 'hash4' }, { date: '2023-11-02', type: 'B', casualties: 8, state: 'NY', country: 'USA', site: 'hash5' }, { date: '2023-11-03', type: 'A', casualties: 25, state: 'NY', country: 'USA', site: 'hash6' }, { date: '2023-11-01', type: 'D', casualties: 12, state: 'NY', country: 'USA', site: 'hash7' }, ]; // 测试阈值9 console.log("阈值为9时:"); const { results: results9, otherCasualties: other9 } = processCasualties(data, 9); console.log(results9); console.log(other9); // 测试阈值13 console.log("阈值为13时:"); const { results: results13, otherCasualties: other13 } = processCasualties(data, 13); console.log(results13); console.log(other13);
修正说明
原代码问题:
- 错误用
type的总伤亡数判断是否保留,不符合规则1(规则要求该type的每一条数据伤亡数都≥阈值); - 未正确统计需聚合的阈值以下
type数量,聚合逻辑错误(直接使用type总伤亡数而非按日期累加); - 缺少聚合后
other数据的日期分组逻辑。
- 错误用
核心修正点:
- 先筛选出所有满足"全日期伤亡数低于阈值"的
type集合; - 根据集合长度判断是否需要聚合为
other; - 对需聚合的
type按日期累加伤亡数,统一生成other条目; - 最后对结果按日期排序,与示例输出顺序匹配。
- 先筛选出所有满足"全日期伤亡数低于阈值"的
内容的提问来源于stack exchange,提问作者user1352042
相关产品推荐
相关产品推荐

