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

JavaScript高性能实现日维度数据按月聚合方案问询

高性能日维度数据按月聚合的JavaScript实现方案

处理上千条日维度数据并按月聚合时,核心要保证O(n)时间复杂度(仅遍历一次原数据),同时减少不必要的内存开销和函数调用。以下是经过验证的最佳实践:

核心思路

用一个临时对象做映射表,键为月份标识(如"Jan 2022"),值为对应月份的聚合数据。遍历原数据时,将每日的uv和pv累加到对应月份的条目里,最后把映射表转为目标数组即可。

基础实现(适合大多数场景)

针对你给出的固定日期格式("数字 月份 年份"),直接用字符串分割提取月份和年份,避免Date对象解析带来的性能损耗:

const aggregateByMonth = (data) => {
  const monthMap = {};
  
  for (const item of data) {
    // 分割日期字符串,提取月份和年份
    const [_, month, year] = item.name.split(' ');
    const monthKey = `${month} ${year}`;
    
    // 若该月份未初始化,则创建新条目
    if (!monthMap[monthKey]) {
      monthMap[monthKey] = {
        name: monthKey,
        uv: 0,
        pv: 0
      };
    }
    
    // 累加uv和pv数据
    monthMap[monthKey].uv += item.uv;
    monthMap[monthKey].pv += item.pv;
  }
  
  // 将映射对象转为数组,得到最终聚合结果
  return Object.values(monthMap);
};

// 测试示例
const rawData = [
  { name: "1 Jan 2022", uv: 2000, pv: 400 },
  { name: "3 Jan 2022", uv: 1000, pv: 1500 },
  { name: "4 Jan 2022", uv: 1000, pv: 500 },
  // 更多数据...
];

const aggregatedData = aggregateByMonth(rawData);
console.log(aggregatedData);

极致性能优化(处理10000+数据时)

如果数据量极大,可替换为基于索引的普通for循环,进一步减少函数调用开销:

const aggregateByMonth = (data) => {
  const monthMap = {};
  const dataLength = data.length;
  
  for (let i = 0; i < dataLength; i++) {
    const item = data[i];
    const [_, month, year] = item.name.split(' ');
    const monthKey = `${month} ${year}`;
    
    // 提前获取条目,减少对象属性访问次数
    let monthEntry = monthMap[monthKey];
    if (!monthEntry) {
      monthEntry = monthMap[monthKey] = { name: monthKey, uv: 0, pv: 0 };
    }
    
    monthEntry.uv += item.uv;
    monthEntry.pv += item.pv;
  }
  
  return Object.values(monthMap);
};

兼容复杂日期格式的方案

如果你的日期格式不固定(如包含不同时区、格式变体),可以用Date对象解析月份,但性能会略低于字符串分割:

// 生成月份标识的辅助函数
const getMonthKey = (dateStr) => {
  const date = new Date(dateStr);
  // 提取缩写月份(如Jan)和完整年份
  const month = date.toLocaleString('en-US', { month: 'short' });
  const year = date.getFullYear();
  return `${month} ${year}`;
};

const aggregateByMonth = (data) => {
  const monthMap = {};
  
  for (const item of data) {
    const monthKey = getMonthKey(item.name);
    
    if (!monthMap[monthKey]) {
      monthMap[monthKey] = { name: monthKey, uv: 0, pv: 0 };
    }
    
    monthMap[monthKey].uv += item.uv;
    monthMap[monthKey].pv += item.pv;
  }
  
  return Object.values(monthMap);
};

关键性能要点

  • 避免循环内重复创建对象:仅在首次遇到新月份时初始化条目
  • 优先用字符串原生方法处理固定格式日期,比Date解析快3-5倍
  • 减少循环内的属性访问次数:提前缓存对象引用

内容的提问来源于stack exchange,提问作者Oscar Ekstrand

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.01 22:25:30