如何将对象数组同类型组内重复name值设为空字符串
JavaScript数组按type分组处理重复name(重复项置空)
原数组
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 resultArr = [ { type: 'F', name: 'Fun Box', age: 12 }, { type: 'X', name: 'X Box', age: 13 }, { type: 'X', name: '', 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: '', age: 17 }, { type: null, name: 'Box One', age: 18 } ]
问题分析
你当前尝试的代码仅对比了当前元素与前一个元素的name,没有按type分组处理,也未记录同一type下所有已出现过的name,因此无法处理跨相邻元素的重复场景(比如type='B'的第三个元素name与同组第一个元素重复,但与前一个元素不同的情况)。
正确实现方案
使用reduce遍历数组,维护一个缓存对象记录每个type下已出现的name集合,遍历过程中处理每个元素的name字段:
const resultArr = arr.reduce((acc, current) => { // 维护缓存:键为type,值为该type下已出现的name集合 const typeKey = current.type === null ? 'null-type' : current.type; if (!acc.seen[typeKey]) { acc.seen[typeKey] = new Set(); } // 创建元素副本,避免修改原数组 const newItem = { ...current }; if (acc.seen[typeKey].has(newItem.name)) { // 同一type下已出现过该name,置空 newItem.name = ''; } else { // 首次出现,加入缓存集合 acc.seen[typeKey].add(newItem.name); } acc.result.push(newItem); return acc; }, { seen: {}, result: [] }).result; console.log(resultArr);
实现思路
- 缓存机制:用
seen对象存储每个type对应的name集合,null类型单独用字符串'null-type'作为键(避免对象键的隐式转换问题)。 - 不修改原数组:通过扩展运算符
{...current}创建元素副本,避免污染原数组数据。 - 重复判断:检查当前元素的
name是否存在于对应type的集合中,存在则置空,否则加入集合并保留原name。
原代码问题说明
你的代码仅对比了当前元素与前一个元素的name,逻辑上存在两个缺陷:
- 未按
type分组,不同type的元素即使name相同也不该被处理(但你的需求是同一type内处理)。 - 未记录同一
type下所有已出现的name,无法处理非相邻的重复场景(比如type='B'的第三个元素)。
内容的提问来源于stack exchange,提问作者imjayabal
相关产品推荐
相关产品推荐

