
本文介绍如何将一个包含 on/off 状态对象的数组,按状态连续变化边界切分为多个子数组(即状态相同时归入同一组,状态切换时开启新组),适用于日志分析、设备状态序列处理等场景。
本文介绍如何将一个包含 `on`/`off` 状态对象的数组,按**状态连续变化边界**切分为多个子数组(即状态相同时归入同一组,状态切换时开启新组),适用于日志分析、设备状态序列处理等场景。
在实际开发中,我们常需对具有时间序号和离散状态(如 'on'/'off')的对象数组进行连续段分组(run-length grouping)——不是简单按状态值聚合(如全部 'on' 放一起),而是识别状态发生切换的时刻,将每一段连续相同状态的数据独立提取为子数组。这种需求广泛存在于设备心跳日志、开关事件流、传感器状态序列等场景中。
实现该逻辑最简洁高效的方式是使用 Array.prototype.reduce() 配合外部状态追踪变量。核心思路是:遍历原数组,维护当前“活跃组索引”和“上一个状态值”;当遇到状态变更时,递增索引并新建分组;否则将当前项推入当前组。
以下是完整可运行的解决方案:
const main_array = [
{ date: "2023-10-02 00:01:00", status: "on" },
{ date: "2023-10-02 00:02:00", status: "on" },
{ date: "2023-10-02 00:03:00", status: "off" },
{ date: "2023-10-02 00:04:00", status: "off" },
{ date: "2023-10-02 00:05:00", status: "off" },
{ date: "2023-10-02 00:06:00", status: "on" },
{ date: "2023-10-02 00:07:00", status: "on" },
{ date: "2023-10-02 00:08:00", status: "on" },
{ date: "2023-10-02 00:09:00", status: "off" },
{ date: "2023-10-02 00:10:00", status: "off" }
];
// 初始化追踪变量
let prevStatus = null;
let groupIndex = 0;
const grouped = main_array.reduce((acc, item) => {
// 状态发生变化 → 新建分组
if (item.status !== prevStatus) {
groupIndex++;
acc[`array${groupIndex}`] = [];
prevStatus = item.status;
}
// 将当前项加入当前分组
acc[`array${groupIndex}`].push(item);
return acc;
}, {});
console.log(grouped);
// 输出:
// {
// array1: [{date: "...", status: "on"}, {date: "...", status: "on"}],
// array2: [{date: "...", status: "off"}, ...],
// array3: [...],
// array4: [...]
// }
✅ 关键要点说明:
- 使用闭包变量 prevStatus 和 groupIndex 实现跨迭代状态记忆,避免在 reduce 回调内重复计算或依赖外部副作用;
- 分组键名采用 array1, array2 等动态生成,便于后续通过 Object.values(grouped) 获取纯数组列表;
- 时间复杂度为 O(n),空间复杂度为 O(n),对千级甚至万级数据量性能稳定;
- 若需返回数组而非对象(如 [[], [], []]),可将 acc 初始化为空数组,并用 acc.push([]) 创建新组,再通过 acc[acc.length - 1].push(item) 操作末尾组。
⚠️ 注意事项:
- 切勿在 reduce 中直接修改初始值(如 {})以外的对象引用,否则可能引发不可预期行为;
- 若输入数组为空,reduce 会抛出错误,建议添加空数组保护:main_array.length === 0 ? {} : main_array.reduce(...);
- 如需支持更多状态值(如 'pending', 'error'),本方案无需修改逻辑,天然兼容任意字符串状态。
该方法兼顾可读性、性能与扩展性,是处理状态连续序列分组问题的推荐实践。
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











