本文介绍如何基于指定属性(如 name)将数组拆分为两个子数组——一个包含所有重复元素(按该属性判定),另一个仅含完全唯一的元素,适用于数据清洗与校验场景。
本文介绍如何基于指定属性(如 name)将数组拆分为两个子数组——一个包含所有重复元素(按该属性判定),另一个仅含完全唯一的元素,适用于数据清洗与校验场景。
在实际前端开发或数据预处理中,常需对对象数组进行去重分析,但不同于简单保留首个出现项的“去重”,有时业务要求显式分离:将所有重复记录(即某字段值出现 ≥2 次的所有对象)归入一个数组供人工审核或修正;其余真正唯一的记录则进入另一数组用于后续流程处理。这种“分而治之”的策略对数据质量管控至关重要。
以下是一个高效、可读性强且时间复杂度为 O(n) 的实现方案,核心思路是使用 Map 按关键属性(如 name)聚类所有对象,再遍历 Map 分别归类:
const customers = [
{ id: 1, name: "John", address: "123 street" },
{ id: 2, name: "Alex", address: "456 street" },
{ id: 3, name: "John", address: "674 street" },
{ id: 4, name: "Stacy", address: "534 street" },
{ id: 5, name: "Blair", address: "634 street" }
];
// 步骤 1:按 name 聚类所有客户对象
const nameGroups = new Map();
for (const customer of customers) {
const list = nameGroups.get(customer.name) || [];
list.push(customer);
nameGroups.set(customer.name, list);
}
// 步骤 2:分离重复组(≥2 个)与唯一组(=1 个)
const duplicates = [];
const uniques = [];
for (const group of nameGroups.values()) {
if (group.length > 1) {
duplicates.push(...group); // 展开全部重复项
} else {
uniques.push(...group); // 展开唯一项
}
}
console.log("重复项(需人工校验):", duplicates);
// → [{ id: 1, name: "John", ... }, { id: 3, name: "John", ... }]
console.log("唯一项(可直接处理):", uniques);
// → [{ id: 2, name: "Alex", ... }, { id: 4, name: "Stacy", ... }, { id: 5, name: "Blair", ... }]✅ 优势说明:
- 使用 Map 避免了嵌套循环,确保线性时间复杂度;
- 保留原始对象引用,不修改原数组结构;
- 支持任意字符串型属性(只需替换 customer.name 为 customer[propertyName] 即可泛化);
- 逻辑清晰,便于单元测试与维护。
⚠️ 注意事项:
立即学习“Java免费学习笔记(深入)”;
- 若属性值为 undefined、null 或非字符串类型(如数字 ID),建议先做安全转换(例如 String(customer.name)),避免 Map 键冲突或误判;
- 对于深层嵌套属性(如 customer.profile.name),需提前做路径校验或使用可选链 ?.;
- 如需保持原始顺序,本方案天然满足(forEach / for...of 遍历 Map 时按插入顺序);
- 若需支持多字段联合去重(如 name + email),可构造复合键:const key =${customer.name}|${customer.email}``。
该方法已在表单批量导入、CRM 数据合并、配置项校验等真实场景中稳定使用,兼顾性能与语义表达力,是 JavaScript 数组精细化分类的推荐实践。










