本文介绍一种高效、原生的 JavaScript 方法:遍历对象数组,对重复出现的 date 值(除首次出现外)自动删除该字段,保留其他所有属性,不改变数组结构与顺序。
本文介绍一种高效、原生的 javascript 方法:遍历对象数组,对重复出现的 `date` 值(除首次出现外)自动删除该字段,保留其他所有属性,不改变数组结构与顺序。
在处理日程、预约或时间序列数据时,常遇到“同一天多条记录”的场景。业务上可能需要保留首条记录的完整信息(含 date),而后续同日期条目仅保留非日期字段(如 start、finish、id)——即「去重但不删行,只删重复的 date 字段」。这不同于常规的数组去重(如 filter() + findIndex() 删除整条对象),而是细粒度的字段级条件删除。
✅ 推荐方案:使用 Set 跟踪已见日期 + map() 构建新数组(推荐)
该方式安全、函数式、不污染原始数据,语义清晰:
const arr = [
{ id: '1', date: '2021-10-01', start: '10:00:00', finish: '12:00:00' },
{ id: '2', date: '2021-10-01', start: '13:00:00', finish: '14:00:00' },
{ id: '3', date: '2021-10-02', start: '13:00:00', finish: '14:00:00' },
{ id: '4', date: '2021-10-03', start: '13:00:00', finish: '14:00:00' }
];
const seenDates = new Set();
const result = arr.map(({ date, ...rest }) => {
if (seenDates.has(date)) {
// 重复日期:返回剔除 date 的对象(保留 id、start、finish 等其余字段)
return { ...rest };
} else {
// 首次出现:保留完整对象(含 date)
seenDates.add(date);
return { date, ...rest };
}
});
console.log(result);
// 输出符合预期:
// [
// { id: '1', date: '2021-10-01', start: '10:00:00', finish: '12:00:00' },
// { id: '2', start: '13:00:00', finish: '14:00:00' },
// { id: '3', date: '2021-10-02', start: '13:00:00', finish: '14:00:00' },
// { id: '4', date: '2021-10-03', start: '13:00:00', finish: '14:00:00' }
// ]
⚠️ 注意事项
- 避免副作用:示例中使用 map() 返回全新数组,原始 arr 不被修改,符合不可变编程原则,推荐用于生产环境。
- delete 方式慎用:虽然可用 forEach() + delete item.date 直接修改原数组对象,但会破坏对象引用一致性,且无法还原;若必须就地修改,请确保下游无依赖原始字段结构的逻辑。
- 键名灵活性:若需适配其他字段(如 eventDate 或 scheduled_at),只需将代码中 'date' 替换为对应 key,并调整解构语法即可。
- 性能表现:Set.prototype.has() 时间复杂度为 O(1),整体算法为 O(n),适用于数千条以内的日常业务数据。
✅ 总结
这种「字段级条件剔除」策略,本质是结合状态记忆(Set)与结构重组(对象解构 + 展开),既精准满足业务需求,又保持代码简洁可维护。无需引入 Lodash 等工具库,纯原生 JavaScript 即可稳健实现——尤其适合前端日程组件、后台数据清洗等真实场景。
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











