如何用JavaScript从对象数组中提取指定键重复的对象?
需求:找出指定键值重复的对象数组
现有如下对象数组:
const items = [ {id: 'uuid-uuu', itemId: 110, nbr: 135, recordID: 222}, {id: 'uuid-www', itemId: 111, nbr: 134, recordID: 555}, {id: 'uuid-xxx', itemId: 111, nbr: 134, recordID: 555}, {id: 'uuid-yyy', itemId: 111, nbr: 134, recordID: 111}, {id: 'uuid-zzz', itemId: 112, nbr: 135, recordID: 222}, ];
需要基于itemId、nbr、recordID这三个键(忽略id及其他未提及的键),找出所有这三个键值完全相同的重复对象,组成新数组。预期结果:
const duplicateItems = [ {id: 'uuid-www', itemId: 111, nbr: 134, recordID: 555}, {id: 'uuid-xxx', itemId: 111, nbr: 134, recordID: 555}, ];
仅需获取重复对象列表,不需要去重或保留唯一对象,要求使用原生JavaScript及ES6+语法。
实现方案
可以结合reduce+Map+filter来实现,逻辑清晰且效率较高,步骤如下:
- 先遍历数组,用
Map统计每个目标键组合的出现次数:- 为每个对象生成唯一标识字符串(由
itemId、nbr、recordID拼接而成) - 用
Map记录该标识对应的出现次数
- 为每个对象生成唯一标识字符串(由
- 再次遍历原数组,过滤出标识出现次数大于1的对象,这些就是需要的重复项。
代码实现
const items = [ {id: 'uuid-uuu', itemId: 110, nbr: 135, recordID: 222}, {id: 'uuid-www', itemId: 111, nbr: 134, recordID: 555}, {id: 'uuid-xxx', itemId: 111, nbr: 134, recordID: 555}, {id: 'uuid-yyy', itemId: 111, nbr: 134, recordID: 111}, {id: 'uuid-zzz', itemId: 112, nbr: 135, recordID: 222}, ]; // 生成目标键组合的唯一标识 const getUniqueKey = ({itemId, nbr, recordID}) => `${itemId}-${nbr}-${recordID}`; // 统计每个键组合的出现次数 const countMap = items.reduce((map, item) => { const key = getUniqueKey(item); map.set(key, (map.get(key) || 0) + 1); return map; }, new Map()); // 筛选出重复的对象 const duplicateItems = items.filter(item => countMap.get(getUniqueKey(item)) > 1); console.log(duplicateItems);
说明
- 时间复杂度为O(n)(n为数组长度),两次遍历都是线性操作
getUniqueKey函数确保相同键组合的对象会被归为同一类,避免误判- 最终通过
filter直接提取所有重复项,保留原对象的完整结构
内容的提问来源于stack exchange,提问作者Ben in CA
相关产品推荐
相关产品推荐

