
本文介绍一种高效、无副作用的方式,使用 set 配合 map 遍历,对对象数组中首次出现以外的重复 name 值统一置为空字符串,保留原始顺序与结构。
本文介绍一种高效、无副作用的方式,使用 set 配合 map 遍历,对对象数组中首次出现以外的重复 name 值统一置为空字符串,保留原始顺序与结构。
在处理前端数据展示(如表格、列表)时,常需对连续重复字段做“去重显示”优化——即仅保留首次出现的值,后续相同值设为空字符串以提升可读性。本例聚焦 name 字段,但方案可轻松扩展至 type、age 或多字段组合去重。
核心思路是:用 Set 记录已出现过的 name 值,在 map 遍历时判断当前项是否为首次出现。若已存在,则返回新对象并置 name: '';否则记录该值并原样返回。注意:此方法不修改原数组(纯函数式),符合现代 JavaScript 最佳实践。
以下是完整实现代码:
const arr = [
{ type: 'F', name: 'Fun Box', age: 12 },
{ type: 'X', name: 'X Box', age: 13 },
{ type: 'X', name: 'X Box', age: 14 },
{ type: 'X', name: 'X Box Test', age: 15 },
{ type: 'B', name: 'Best Box', age: 16 },
{ type: 'B', name: 'Best Box Test', age: 15 },
{ type: 'B', name: 'Best Box', age: 17 },
{ type: null, name: 'Box One', age: 18 }
];
const seenNames = new Set();
const resultArr = arr.map(item => {
if (seenNames.has(item.name)) {
return { ...item, name: '' };
}
seenNames.add(item.name);
return item;
});
console.log(resultArr);
// 输出即为预期结果:重复 name(如第二个 'X Box'、第二个 'Best Box')已被清空✅ 关键优势说明:
- ✅ 稳定可靠:
Set查找时间复杂度为 O(1),整体性能优于indexOf或filter等方案; - ✅ 安全不可变:使用展开语法
{...item}创建新对象,避免意外修改原数组; - ✅ 兼容性强:支持
null、undefined、空字符串等边界值(Set可正常存储null,不影响逻辑); - ✅ 易于扩展:如需按
type + name联合去重,只需将seenNames.add(item.name)改为seenNames.add(${item.type}-${item.name})。
⚠️ 注意事项:
- 该逻辑基于全局唯一性判定(即整个数组内首次出现为准),而非相邻重复。若需仅处理连续重复(如
['A','A','B','A']中只清空第二个'A'),应改用reduce或带前项比对的for循环; - 若
name字段可能为undefined或null,且你希望将其视作“相同值”统一去重,请提前标准化(例如String(item.name)),否则null和undefined在Set中被视为不同值。
掌握这一模式后,你可快速适配各类“首显去重”场景——无论是渲染树形结构、生成分组报表,还是导出 Excel 表格,都能让数据更清晰、专业。

















