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

如何在TypeScript中从时间序列对象数组获取每月最后一天的数据

问题:提取时间序列中每月最后一天的数据

我从API获取了随机日期的时间序列数据,格式如下:

[
  {
    "id": 1,
    "score": 23,
    "date": "2023-08-30"
  },
  {
    "id": 2,
    "score": 62,
    "date": "2023-08-22"
  },
  {
    "id": 3,
    "score": 82,
    "date": "2023-07-27"
  }
  // ... 更多数据
]

需要优雅提取序列中每月最后一天的数据,期望结果示例:

[
  {
    "id": 1,
    "score": 23,
    "date": "2023-08-30"
  },
  {
    "id": 3,
    "score": 82,
    "date": "2023-07-27"
  }
  // ... 更多数据
]

我目前的代码框架如下:

const getMonthlydata = (allData: Timeseries[]): Timeseries[] => {
  // Loop over every item to get max date of every month and add it to return array
}

解决方案

可以通过按年月分组 + 每组筛选最晚日期的方式实现,逻辑清晰且效率较高:

interface Timeseries {
  id: number;
  score: number;
  date: string;
}

const getMonthlydata = (allData: Timeseries[]): Timeseries[] => {
  // 按「年-月」分组,存储每组中日期最晚的那条数据
  const monthlyMap = new Map<string, Timeseries>();

  allData.forEach(item => {
    // 提取日期的「年-月」部分作为分组键
    const yearMonth = item.date.slice(0, 7);
    const existingItem = monthlyMap.get(yearMonth);

    // 若当前分组无数据,或当前条目日期更晚,则更新分组数据
    if (!existingItem || new Date(item.date) > new Date(existingItem.date)) {
      monthlyMap.set(yearMonth, item);
    }
  });

  // 将Map中的值转为数组返回
  return Array.from(monthlyMap.values());
}

逻辑说明:

  • 用Map按年-月(如2023-08)分组,避免重复遍历
  • 遍历每条数据时,对比当前分组内已有的最晚日期数据,保留更新的那条
  • 最终把Map的value转为数组,得到每个月数据中日期最晚的条目

如果需要严格筛选当月实际最后一天(而非数据中存在的最晚日期),可以加一步验证:

// 辅助函数:判断日期是否为当月最后一天
const isLastDayOfMonth = (dateStr: string): boolean => {
  const date = new Date(dateStr);
  // 计算下月第一天,再往前推一天就是当月最后一天
  const nextMonthFirstDay = new Date(date.getFullYear(), date.getMonth() + 1, 1);
  const lastDayOfMonth = new Date(nextMonthFirstDay.getTime() - 24 * 60 * 60 * 1000);
  return date.toDateString() === lastDayOfMonth.toDateString();
};

// 修改后的方法:仅保留实际当月最后一天的数据
const getMonthlydata = (allData: Timeseries[]): Timeseries[] => {
  const monthlyMap = new Map<string, Timeseries>();

  allData.forEach(item => {
    const yearMonth = item.date.slice(0, 7);
    const existingItem = monthlyMap.get(yearMonth);

    if (!existingItem || new Date(item.date) > new Date(existingItem.date)) {
      monthlyMap.set(yearMonth, item);
    }
  });

  // 过滤出符合实际当月最后一天的数据
  return Array.from(monthlyMap.values()).filter(item => isLastDayOfMonth(item.date));
}

内容的提问来源于stack exchange,提问作者Annas Rafique

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.11 15:57:35