React & JavaScript:移除数组中重复办公代码对象问题求助
问题:React/JS中对象数组去重失败的原因与解决方法
我正在React与JavaScript环境中开发,现有如下结构的数组对象:
const Regions = [ { REGION_CODE: 'ABC', REGION_NAME: 'SOMEREGION1', OFFICES: [ {OFFICE_CODE: 'ABD', OFFICE_NAME: 'SOMEOFFICE'}, ... // 该区域下有数十个唯一条目 ]}, { REGION_CODE: 'ABD', REGION_NAME: 'SOMEREGION2', OFFICES: [ {OFFICE_CODE: 'CDF', OFFICE_NAME: 'SOMEOFFICE2'} ... // 该区域下有数十个唯一条目 ]}, ... // 多个类似结构的条目 ]
当前问题是:多个Regions条目中的OFFICES存在与其他区域重复的OFFICE_CODE。我的目标是实现一个搜索筛选器,当选择“所有区域”时展示所有唯一的办公代码。但查阅相关问答后尝试的方法均无法移除重复项。
我尝试了以下三种方案:
//Variant 1 const Offices = [] Regions.forEach(region => { region.OFFICES.forEach(office => { if(!Offices.includes(office)) { Offices.push(office) } }) }); //Variant 2 const Offices = [] Regions.forEach(region => { region.OFFICES.forEach(office => { if(Offices.indexOf(office) === -1) { Offices.push(office) } }) }); //Variant 3 const Offices = [] Regions.forEach(region => { region.OFFICES.forEach(office => { Offices.push(office) }) }); const UniqueOffices = Array.from(new Set(Offices));
我认为上述方法应该有效,但结果始终返回所有条目而非唯一项。我也尝试过map版本,但几乎可以肯定自己存在理解误区。当我将数组简化为如下形式时:
const item = [ 'a', 'b', 'c', 'd', 'c', 'a']
或
const item = [ 1, 2, 3, 3, 2, 4 ]
上述方法均能正常工作。
请问我哪里出错了?有什么修复建议?
错误原因
核心问题在于JavaScript中对象是引用类型,而非值类型:
- 字符串、数字等值类型,
includes、indexOf或Set直接比较值的内容,因此能正确去重。 - 但对于对象,即使两个对象的
OFFICE_CODE和OFFICE_NAME完全一致,它们也是内存中独立的引用地址。includes、indexOf会比较引用地址而非对象内容;Set同样基于引用地址判断唯一性,因此这些方法无法识别属性相同的重复对象。
修复方案
我们需要基于对象的唯一标识(OFFICE_CODE)来判断重复,以下是几种可行实现:
方案1:用Set记录已出现的办公代码
const seenCodes = new Set(); const uniqueOffices = []; Regions.forEach(region => { region.OFFICES.forEach(office => { if (!seenCodes.has(office.OFFICE_CODE)) { seenCodes.add(office.OFFICE_CODE); uniqueOffices.push(office); } }); });
思路:用Set存储已处理的OFFICE_CODE,遍历办公对象时先检查代码是否已存在,不存在则添加到结果数组和Set中。
方案2:用reduce结合对象去重
// 先提取所有办公对象到一维数组,再去重 const uniqueOfficesObj = Regions.flatMap(region => region.OFFICES) .reduce((acc, office) => { if (!acc[office.OFFICE_CODE]) { acc[office.OFFICE_CODE] = office; } return acc; }, {}); // 转换为数组形式 const uniqueOfficesArray = Object.values(uniqueOfficesObj);
思路:用flatMap扁平化所有办公对象,再通过reduce以OFFICE_CODE为键存储对象(重复键会自动覆盖),最后将对象值转为数组。
方案3:用Map存储唯一对象
const officeMap = new Map(); Regions.forEach(region => { region.OFFICES.forEach(office => { if (!officeMap.has(office.OFFICE_CODE)) { officeMap.set(office.OFFICE_CODE, office); } }); }); const uniqueOffices = Array.from(officeMap.values());
思路:类似Set的逻辑,用Map直接存储OFFICE_CODE与对应对象的键值对,最后提取所有值得到唯一对象数组。
内容的提问来源于stack exchange,提问作者Azu
相关产品推荐
相关产品推荐

