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

如何用Lodash按今日、昨日、近7天及月份分组时间对象数组?

按「今日/昨日/近7天/年月」分组时间戳数组的实现方案

需求说明

我有一个包含标题和时间戳的对象数组,想要按「今日」「昨日」「近7天」「年月(如2023年1月)」的结构分组。目前已经用Lodash的groupBy实现了按年月分组,想请教怎么加上前面三个分组的逻辑。

原数组示例

const listOfObjects = [
  {
    title: "标题1",
    date: "今日的时间戳"
  },
  {
    title: "标题2",
    date: "昨日的时间戳"
  },
  {
    title: "标题3",
    date: "昨日的时间戳"
  },
  {
    title: "标题4",
    date: "近7天内某一天的时间戳"
  },
  {
    title: "标题5",
    date: "上个月的时间戳"
  },
  // ...更多数据
]

目标分组结构

const structeredObjects = {
  "今日": [{
    title: "标题1",
    date: "今日的时间戳"
  }],
  "昨日": [{
    title: "标题2",
    date: "昨日的时间戳"
  },
  {
    title: "标题3",
    date: "昨日的时间戳"
  }],
  "近7天": [{
    title: "标题4",
    date: "近7天内某一天的时间戳"
  }],
  "2023年1月": [{
    title: "标题5",
    date: "时间戳"
  }],
  "2022年12月": [{
    title: "标题6",
    date: "时间戳"
  }],
  // ...更多分组
}

核心思路

先给每个元素分配一个分组键,优先级顺序为:今日 > 昨日 > 近7天(排除已分到今日/昨日的元素)> 年月。随后用Lodash的groupBy根据这个键完成分组,最后调整分组顺序,确保「今日」「昨日」「近7天」排在所有年月分组的前面。

实现代码

1. 时间工具函数

先封装几个用于判断时间归属和格式化的工具函数:

// 获取当天0点的时间戳(避免跨小时判断误差)
const getTodayStart = () => {
  const now = new Date();
  now.setHours(0, 0, 0, 0);
  return now.getTime();
};

// 获取昨日0点的时间戳
const getYesterdayStart = () => getTodayStart() - 24 * 60 * 60 * 1000;

// 获取7天前0点的时间戳
const getSevenDaysAgoStart = () => getTodayStart() - 7 * 24 * 60 * 60 * 1000;

// 将时间戳格式化为「YYYY年MM月」的字符串
const formatYearMonth = (timestamp) => {
  const date = new Date(timestamp);
  const year = date.getFullYear();
  const month = (date.getMonth() + 1).toString().padStart(2, '0'); // 月份从0开始,需+1并补零
  return `${year}年${month}月`;
};

2. 分组键判断逻辑

为每个元素生成对应的分组键:

const getGroupKey = (item) => {
  const itemTime = parseInt(item.date, 10);
  const todayStart = getTodayStart();
  const yesterdayStart = getYesterdayStart();
  const sevenDaysAgoStart = getSevenDaysAgoStart();

  if (itemTime >= todayStart) {
    return "今日";
  } else if (itemTime >= yesterdayStart) {
    return "昨日";
  } else if (itemTime >= sevenDaysAgoStart) {
    return "近7天";
  } else {
    return formatYearMonth(itemTime);
  }
};

3. 执行分组并调整顺序

用Lodash的groupBy分组后,调整分组的显示顺序:

import _ from 'lodash';

// 按分组键进行分组
const grouped = _.groupBy(listOfObjects, getGroupKey);

// 构建有序的分组结果,先处理「今日」「昨日」「近7天」
const orderedResult = {};
["今日", "昨日", "近7天"].forEach(key => {
  if (grouped[key]) {
    orderedResult[key] = grouped[key];
    delete grouped[key];
  }
});

// 将剩余的年月分组按时间倒序排列(最新月份在前)
const sortedMonthGroups = Object.entries(grouped)
  .sort(([monthA], [monthB]) => new Date(monthB) - new Date(monthA))
  .reduce((acc, [key, value]) => {
    acc[key] = value;
    return acc;
  }, {});

// 合并得到最终结果
const finalStructuredObjects = {...orderedResult, ...sortedMonthGroups};

注意事项

  • 所有时间判断都基于当天0点的时间戳,避免因当前小时导致的判断错误;
  • 「近7天」分组会自动排除已分到「今日」「昨日」的元素,不会出现重复分组;
  • 如果某个分组没有数据(比如今日无内容),对应的键不会出现在最终结果中;
  • 年月分组会按时间倒序排列,保证最新的月份显示在最前面。

内容的提问来源于stack exchange,提问作者Christian Schweinhardt

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.02 21:50:39