JavaScript中嵌套对象按季度聚合(非ES6实现)咨询
非ES6实现:嵌套对象月度数据转季度聚合
针对你提出的将多层嵌套对象中的月度合同数据按季度(每3个月)聚合的需求,我整理了一套兼容ES5及更早版本的实现方案,完全基于传统的对象遍历和累加逻辑完成,不需要依赖ES6的新特性。
核心思路
我们需要逐层遍历嵌套的对象结构:
- 第一层:遍历所有办公地点(比如California、North Carolina)
- 第二层:遍历每个地点下的所有合同(Contract1、Contract2等)
- 第三层:遍历每个合同下的月度数据,计算对应季度的Price和Count总和
- 季度编号计算:
Math.floor((month - 1) / 3) + 1,比如1-3月对应季度1,4-6月对应季度2,以此类推 - 对每个季度,累加对应月份的Price和Count值
- 季度编号计算:
完整实现代码
function aggregateQuarterlyData(officeData) { // 创建最终结果对象 var result = { Office: {} }; var office = officeData.Office; // 遍历所有办公地点 for (var state in office) { if (office.hasOwnProperty(state)) { result.Office[state] = {}; var contracts = office[state]; // 遍历当前地点下的所有合同 for (var contractName in contracts) { if (contracts.hasOwnProperty(contractName)) { result.Office[state][contractName] = {}; var monthlyData = contracts[contractName]; var quarterlyData = result.Office[state][contractName]; // 遍历每个月度数据,计算季度聚合 for (var monthStr in monthlyData) { if (monthlyData.hasOwnProperty(monthStr)) { var month = parseInt(monthStr, 10); var quarter = Math.floor((month - 1) / 3) + 1; var monthItem = monthlyData[monthStr]; // 如果该季度还未初始化,先创建空对象 if (!quarterlyData[quarter]) { quarterlyData[quarter] = { Price: 0, Count: 0 }; } // 累加Price和Count quarterlyData[quarter].Price += monthItem.Price; quarterlyData[quarter].Count += monthItem.Count; } } } } } } return result; } // 测试使用示例 var originalData = { "Office": { "California" : { "Contract1": { 1: {Price: 1000, Count: 5}, 2: {Price: 2000, Count: 11}, 3: {Price: 3000, Count: 3}, 4: {Price: 2000, Count: 1} }, "Contract2": { 1: {Price: 7000, Count: 6}, 2: {Price: 1000, Count: 4}, 3: {Price: 67000, Count: 6}, 4: {Price: 500, Count: 2} }, "Contract3": { 1: {Price: 4000, Count: 4}, 2: {Price: 4000, Count: 1}, 3: {Price: 5000, Count: 12}, 4: {Price: 5000, Count: 2} } }, "North Carolina" : { "Contract1": { 1: {Price: 7000, Count: 4}, 2: {Price: 7000, Count: 4}, 3: {Price: 7000, Count: 4}, 4: {Price: 7000, Count: 4} }, "Contract2": { 1: {Price: 6000, Count: 4}, 2: {Price: 2000, Count: 10}, 3: {Price: 3000, Count: 3}, 4: {Price: 2000, Count: 3} }, "Contract3": { 1: {Price: 4000, Count: 5}, 2: {Price: 2000, Count: 4}, 3: {Price: 4000, Count: 3}, 4: {Price: 2000, Count: 4} } } } }; var aggregatedData = aggregateQuarterlyData(originalData); console.log(JSON.stringify(aggregatedData, null, 2));
关键细节说明
hasOwnProperty检查:遍历对象属性时必须加上这个判断,避免遍历到对象原型链上的继承属性,保证数据处理的准确性。- 季度编号计算:通过
Math.floor((month - 1) / 3) + 1把1-12月映射到1-4季度,这个逻辑能兼容任意月份数的输入(哪怕不是完整的12个月)。 - 累加逻辑:每个季度的初始值需要先初始化,再进行累加操作,避免出现
undefined的错误。 - 非ES6兼容:全程使用
var声明变量,传统for...in遍历对象,没有使用任何ES6+的语法特性,能在旧版浏览器或环境中正常运行。
你可以直接把自己的原始数据传入aggregateQuarterlyData函数,就能得到完全匹配需求的季度聚合结果。
内容的提问来源于stack exchange,提问作者MountainMJ
相关产品推荐
相关产品推荐

