位置:首页 > JavaScript > 数组对象如何按连续相同type字段分组聚合处理

数组对象如何按连续相同type字段分组聚合处理

时间:2026-08-15  |  作者:宇宙开黑者  |  阅读:0

本文介绍一种高效方法,将对象数组按 type 字段的连续相同值进行分组,生成包含 type 和对应 values 数组的结构化结果,而非全局去重,关键在于识别“相邻重复”而非“所有重复”。

如何按连续相同 type 字段对数组对象进行分组聚合

本文介绍一种高效方法,将对象数组按 `type` 字段的**连续相同值**进行分组,生成包含 `type` 和对应 `values` 数组的结构化结果,而非全局去重,关键在于识别“相邻重复”而非“所有重复”。

放到真实业务里看,这类需求其实非常常见,比如时间线事件归类、日志流分段、状态序列聚合。很多时候,需要把类型一致且物理位置连续的对象,整理成一个个逻辑区块。举个最直接的例子:如果连续出现多个 "type": "A" 对象,它们就应该合并成同一个区块;但只要中间插入一个 "type": "B",前面的 "A" 区块就到此为止,新的 "B" 区块随即开始;而后面如果又连续出现 "A",也不能再并回前一个区块,而是要当作一个全新的独立区块处理——这才是“按连续相同字段分组”真正要表达的核心语义。

实现该逻辑最简洁、可读性最强的方式是使用 Array.prototype.reduce() 一次遍历完成:

const data = [
{ object: 1, start: "2018-07-08", end: "2018-12-31", type: "A", user: "ABCD" },
{ object: 2, start: "2018-12-31", end: "2019-06-26", type: "A", user: "ABCD" },
{ object: 3, start: "2019-06-26", end: "2019-12-31", type: "B", user: "PQRS" },
{ object: 4, start: "2019-12-31", end: "2020-06-31", type: "B", user: "PQRS" },
{ object: 5, start: "2024-12-31", end: "2024-12-31", type: "A", user: "ABCD" },
{ object: 6, start: "2012-12-31", end: "2024-06-26", type: "A", user: "ABCD" },
{ object: 7, start: "2024-06-26", end: "2024-12-31", type: "A", user: "ABCD" },
{ object: 8, start: "2024-12-31", end: "2024-06-26", type: "A", user: "ABCD" }
];

const grouped = data.reduce((result, current) => {
// 检查 result 中最后一个分组是否存在,且其 type 是否与当前对象一致
const lastGroup = result.at(-1);
if (lastGroup && lastGroup.type === current.type) {
lastGroup.values.push(current);
} else {
// 创建新分组:固定结构 { type, values: [current] }
result.push({ type: current.type, values: [current] });
}
return result;
}, []);

console.log(grouped);
// 输出符合预期的三段式分组结构

关键要点说明:

  • result.at(-1) 安全获取最后分组(ES2024+,兼容性好;若需支持旧环境,可用 result[result.length - 1] 替代);
  • 判断条件 lastGroup && lastGroup.type === current.type 确保仅对紧邻的相同 type 进行追加,严格满足“立即连续”语义;
  • 每个分组结构统一为 { type: string, values: Array },语义清晰、易于后续消费(如渲染为折叠面板、生成时间轴等);
  • 时间复杂度 O(n),空间复杂度 O(n),无额外遍历或查找,性能最优。
  • 注意事项:

    • 此方案不改变原始数组顺序,分组完全依赖输入顺序,适用于已按时间/逻辑序排列的数据;
    • 若输入数据未排序或存在乱序 type,结果将反映实际相邻关系,而非业务意义上的“同类合并”——请确保上游数据已按业务规则预排序;
    • reduce 的初始值 [] 是空数组,确保首次迭代时 lastGroupundefined,自然触发新分组创建。

    这个模式的扩展性其实很强。比如,想同时按 typeuser 两个字段做连续分组,只需要把判断条件改成 lastGroup.type === current.type && lastGroup.user === current.user 就够了;如果还要补充统计信息,例如每组的起止时间,也可以在 push 时或 push 之后顺手同步算出来。把这套思路吃透,处理各种“连续序列聚合”场景,基本都会更高效、更顺手。

    免责声明:文中图文均来自网络,如有侵权请联系删除,心愿游戏发布此文仅为传递信息,不代表心愿游戏认同其观点或证实其描述。

    精选合集

    更多

    大家都在玩