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

如何按相同id、startDate和endDate分组JavaScript对象数组?

分组对象数组:按id、startDate和endDate完全匹配分组

需求:将对象数组中id、startDate、endDate三者完全相同的对象分组。规则:仅id相同但日期不同不分组;仅日期相同但id不同也不分组。

我尝试用forEach实现但未成功,代码如下:

const newDates: any[] = [];
response.forEach((elem, index) => {
    if(newDates.length === 0) newDates.push([elem])

    if(newDates.length > 0) {
        if(
            newDates[index][0].startDate === elem.startDate
            && newDates[index][0].endDate === elem.endDate
            && newDates[index][0].id === elem.id
        ) {
            newDates[index].push(elem)
        } else {
            newDates.push([elem])
        }
    }
})

示例输入

const response = [
    {
        name: 'John',
        id: 1,
        startDate:'2022-10-31T00:00:00',
        endDate: '2022-12-01T00:00:00'
    },
    {
        name: 'Alisha',
        id: 1,
        startDate:'2022-10-31T00:00:00',
        endDate: '2022-12-01T00:00:00'
    },
    {
        name: 'Andrew',
        id: 4,
        startDate:'2022-10-05T00:00:00',
        endDate: '2022-11-01T00:00:00'
    },
    {
        name: 'James',
        id: 4,
        startDate:'2022-10-05T00:00:00',
        endDate: '2022-11-01T00:00:00'
    },
    {
        name: 'Kamilla',
        id: 4,
        startDate:'2022-11-14T00:00:00',
        endDate: '2022-11-18T00:00:00'
    },
    {
        name: 'Oliver',
        id: 4,
        startDate:'2022-11-13T00:00:00',
        endDate: '2022-11-18T00:00:00'
    }
]

期望输出

const result = [
    [
        {
            name: 'John',
            id: 1,
            startDate:'2022-10-31T00:00:00',
            endDate: '2022-12-01T00:00:00'
        },
        {
            name: 'Alisha',
            id: 1,
            startDate:'2022-10-31T00:00:00',
            endDate: '2022-12-01T00:00:00'
        },
    ],
    [
        {
            name: 'Andrew',
            id: 4,
            startDate:'2022-10-05T00:00:00',
            endDate: '2022-11-01T00:00:00'
        },
        {
            name: 'James',
            id: 4,
            startDate:'2022-10-05T00:00:00',
            endDate: '2022-11-01T00:00:00'
        },
    ],
    [
        {
            name: 'Kamilla',
            id: 4,
            startDate:'2022-11-14T00:00:00',
            endDate: '2022-11-18T00:00:00'
        }
    ],
    [
        {
            name: 'Oliver',
            id: 4,
            startDate:'2022-11-13T00:00:00',
            endDate: '2022-11-18T00:00:00'
        }
    ]
]

问题分析

原代码的核心错误是用response的索引index去匹配newDates的元素,逻辑完全不成立:

  • newDates的长度和response不同步,当index >= newDates.length时会直接报错
  • 仅和当前索引对应的组比较,不会检查所有已存在的组,导致符合条件的对象无法进入正确的组

正确实现(用reduce)

用reduce构建一个以id-startDate-endDate为键的对象,将相同键的对象归到同一数组,最后提取所有值即可得到分组结果:

const result = response.reduce((acc, elem) => {
    // 生成唯一分组键:组合id、startDate、endDate
    const key = `${elem.id}-${elem.startDate}-${elem.endDate}`;
    // 如果键不存在,初始化空数组
    if (!acc[key]) {
        acc[key] = [];
    }
    // 将当前对象加入对应组
    acc[key].push(elem);
    return acc;
}, {} as Record<string, typeof response>);

// 将对象的值转为数组,得到最终分组结果
const groupedResult = Object.values(result);

运行上述代码后,groupedResult的结构完全符合期望输出。


内容的提问来源于stack exchange,提问作者Александр Мерный

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.13 05:05:14