广告

JavaScript按name属性对数组对象去重并保留重复项的完整实现(含代码示例)

1. 背景与需求

1.1 场景描述

在处理来自后端传输的对象数组时,需要按 name 属性去重,同时保留重复项以便差异对比和后续处理。

本文聚焦于 按 name 属性对数组对象去重并保留重复项的完整实现,并给出可直接运行的 JavaScript 代码示例

2. 设计方案

2.1 关键点

核心目标是得到一个 唯一项数组(按 name 去重的第一条记录)和一个 重复项数组(后续出现的同名对象)。

为了实现高效性,采用 单遍历 + 辅助集合 的思路,时间复杂度接近 O(n),空间复杂度为 O(k),其中 k 为不同 name 的数量。

3. 具体实现要点

3.1 数据结构与边界处理

若对象缺少 name 属性,本文将其视为单独项,放入 唯一项数组,确保边界行为的一致性。

对于 name 重复的对象,只有第一次出现被放入 唯一项数组,其后出现的将进入 重复项数组

4. 完整实现代码

4.1 函数实现

下面给出一个可直接使用的实现,包含 输入示例返回结构用法示例

function dedupeByNamePreserveDuplicates(arr) {// 使用 Set 记录已出现的 nameconst seen = new Set();const unique = [];const duplicates = [];for (const item of arr) {// 假设对象有 name 属性,若没有则将其视为唯一项const key = item && item.name;if (key === undefined) {unique.push(item);continue;}if (seen.has(key)) {// name 已出现,放入重复项duplicates.push(item);} else {// 首次出现,放入唯一项并标记seen.add(key);unique.push(item);}}return { unique, duplicates };
}// 使用示例
const data = [{ id: 1, name: 'Alice', age: 30 },{ id: 2, name: 'Bob', age: 25 },{ id: 3, name: 'Alice', age: 28 },{ id: 4, name: 'Charlie', age: 35 },{ id: 5, name: 'Bob', age: 27 },{ id: 6, name: 'Dana' },{ id: 7, age: 40 } // 无 name,视为唯一项
];const { unique, duplicates } = dedupeByNamePreserveDuplicates(data);console.log('唯一项:', unique);
console.log('重复项:', duplicates);

5. 扩展实现与变体

5.1 使用 Map 的实现变体

若需要保留同名的所有对象并以分组形式返回,可以改用 Map<name, Array> 进行分组,然后再把分组结果转换为所需结构。

下面给出 transformer 的思路:先遍历一次,将每个 name 对应的所有对象放入 Map 的数组中,最后再将 Map 的键值对转为包含 唯一项集合分组项集合的结构。

function groupByName(arr) {const map = new Map();for (const item of arr) {const key = item && item.name;if (key === undefined) {// 放在特殊分组或忽略if (!map.has('__NO_NAME__')) map.set('__NO_NAME__', []);map.get('__NO_NAME__').push(item);continue;}if (!map.has(key)) map.set(key, []);map.get(key).push(item);}return map;
}

JavaScript按name属性对数组对象去重并保留重复项的完整实现(含代码示例)

广告