如何基于多个属性从Observable数组中移除重复项?
数组去重并修改属性的实现方案
需求说明
原始数组:
[ {id: 1, name: 'Sam', gender: 'boy'}, {id: 2, name: 'Mary', gender: 'girl'}, {id: 3, name: 'Sam', gender: 'boy'} ]
需要达成两个目标:
- 仅基于
name和gender属性去重,保留首次出现的条目 - 将对象中的
gender属性重命名为type
最终期望结果:
[ {id: 1, name: 'Sam', type: 'boy'}, {id: 2, name: 'Mary', type: 'girl'} ]
实现方法
方法一:Map遍历处理
利用Map的键唯一性特性,以name+gender组合作为唯一标识,遍历数组时仅保留首次出现的条目,同时完成属性重命名:
const originalArray = [ {id: 1, name: 'Sam', gender: 'boy'}, {id: 2, name: 'Mary', gender: 'girl'}, {id: 3, name: 'Sam', gender: 'boy'} ]; const uniqueMap = new Map(); originalArray.forEach(item => { // 生成唯一键:name与gender的组合 const uniqueKey = `${item.name}-${item.gender}`; if (!uniqueMap.has(uniqueKey)) { // 解构移除gender属性,同时添加type属性 const { gender, ...restProps } = item; uniqueMap.set(uniqueKey, { ...restProps, type: gender }); } }); // 将Map的值转换为数组,得到最终结果 const result = Array.from(uniqueMap.values()); console.log(result);
方法二:reduce简化代码
用reduce方法整合遍历与Map构建逻辑,代码更紧凑:
const originalArray = [ {id: 1, name: 'Sam', gender: 'boy'}, {id: 2, name: 'Mary', gender: 'girl'}, {id: 3, name: 'Sam', gender: 'boy'} ]; const result = Array.from( originalArray.reduce((map, item) => { const uniqueKey = `${item.name}-${item.gender}`; if (!map.has(uniqueKey)) { const { gender, ...restProps } = item; map.set(uniqueKey, { ...restProps, type: gender }); } return map; }, new Map()).values() ); console.log(result);
核心逻辑说明
- 唯一标识:通过
name和gender拼接成字符串作为唯一键,确保相同组合的对象只会被保留一次 - 属性重命名:通过对象解构语法,移除原有的
gender属性,同时新增type属性并赋值为原gender的值 - 顺序保留:Map会按照键的插入顺序存储值,因此能保留原始数组中首次出现的条目
内容的提问来源于stack exchange,提问作者Homer
相关产品推荐
相关产品推荐

