JavaScript 中按指定属性分离唯一项与重复项的高效实现

3次阅读

JavaScript 中按指定属性分离唯一项与重复项的高效实现

本文介绍如何在 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() 的低效组合,是兼顾性能、可读性与工程实践的推荐解法。

text=ZqhQzanResources