
本文介绍如何在 javaScript 中基于对象属性(如 name)将数组拆分为两个独立数组:一个包含所有重复出现的元素,另一个仅含首次出现且无重复的元素,适用于数据清洗与校验场景。
本文介绍如何在 javascript 中基于对象属性(如 `name`)将数组拆分为两个独立数组:一个包含所有重复出现的元素,另一个仅含首次出现且无重复的元素,适用于数据清洗与校验场景。
在实际前端开发或数据处理中,常需对用户导入的结构化数据(如客户列表)进行去重预检——但不同于简单保留首个副本,业务逻辑往往要求显式分离重复项与唯一项:前者交由用户人工核对修正,后者直接进入后续流程。本方案提供一种时间复杂度为 O(n)、语义清晰且易于维护的实现方式。
核心思路是利用 map 按关键属性(如 name)聚合同名对象,再遍历分组结果,将长度大于 1 的组展开至重复数组,长度为 1 的组归入唯一数组:
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(); customers.foreach(customer => { const list = nameGroups.get(customer.name) || []; list.push(customer); nameGroups.set(customer.name, list); }); // 步骤 2:分离重复项(≥2 个同名)与唯一项(仅 1 个) const duplicates = []; const uniques = []; nameGroups.forEach((group, name) => { 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", ... }]
✅ 优势说明:
- 稳定性:严格保留原始顺序(因 forEach 遍历 Map 保持插入序,且 push(…group) 不打乱组内顺序);
- 可扩展性:只需修改 customer.name 为任意属性(如 customer.email 或 customer.phone),即可适配不同去重维度;
- 健壮性:自动处理空值或 undefined 属性(建议前置校验,见下方注意事项)。
⚠️ 注意事项:
立即学习“Java免费学习笔记(深入)”;
- 若 name 可能为 NULL/undefined,需先做规范化处理(例如 String(customer.name || ”)),避免 Map 键冲突;
- 对于大小写敏感场景(如 “john” 和 “John” 视为不同),可统一转小写后再分组:customer.name?.toLowerCase();
- 如需支持多字段联合去重(如 name + email),可构造复合键:const key =${customer.name}|${customer.email}“。
该方法规避了嵌套循环的 O(n²) 开销,也优于多次 Filter() + findIndex() 的低效组合,是兼顾性能、可读性与工程实践的推荐解法。