如何从对象数组中提取属性值重复的对象及去重后的数组
如何筛选JavaScript数组中attr属性重复和唯一的对象
针对你给出的数组需求,我整理了几种简单高效的实现方式,核心思路都是先统计每个attr值的出现次数,再基于次数进行筛选:
方法一:使用普通对象统计次数(最常用)
这种方法兼容性好,代码简洁,适合大多数场景:
var array = [{"id":1,"attr":5},{"id":2,"attr":3},{"id":3,"attr":5}]; // 1. 统计每个attr的出现次数 const attrCount = {}; array.forEach(item => { attrCount[item.attr] = (attrCount[item.attr] || 0) + 1; }); // 2. 筛选出attr重复的对象(出现次数>1) const duplicateItems = array.filter(item => attrCount[item.attr] > 1); // 3. 筛选出attr唯一的对象(出现次数=1) const uniqueItems = array.filter(item => attrCount[item.attr] === 1); console.log("重复attr的对象:", duplicateItems); // 输出: [{"id":1,"attr":5},{"id":3,"attr":5}] console.log("唯一attr的对象:", uniqueItems); // 输出: [{"id":2,"attr":3}]
代码说明:
- 第一步遍历数组,用
attrCount对象记录每个attr值出现的次数; - 第二步和第三步分别用
filter方法,根据attrCount中的次数筛选目标数组; - 时间复杂度为O(n),整体效率很高。
方法二:使用Map统计次数(更灵活)
如果你的attr值可能是非字符串/数字类型(比如对象),用Map会更合适,它支持任意类型的键:
var array = [{"id":1,"attr":5},{"id":2,"attr":3},{"id":3,"attr":5}]; const attrMap = new Map(); array.forEach(item => { attrMap.set(item.attr, (attrMap.get(item.attr) || 0) + 1); }); const duplicateItems = array.filter(item => attrMap.get(item.attr) > 1); const uniqueItems = array.filter(item => attrMap.get(item.attr) === 1); console.log("重复attr的对象:", duplicateItems); console.log("唯一attr的对象:", uniqueItems);
方法三:一次遍历完成分类(减少遍历次数)
如果追求极致的遍历次数,可以在第二次遍历时直接将对象分到对应的数组中,只需要两次遍历:
var array = [{"id":1,"attr":5},{"id":2,"attr":3},{"id":3,"attr":5}]; const attrCount = {}; const duplicateItems = []; const uniqueItems = []; // 第一次遍历:统计次数 array.forEach(item => { attrCount[item.attr] = (attrCount[item.attr] || 0) + 1; }); // 第二次遍历:直接分类 array.forEach(item => { if (attrCount[item.attr] > 1) { duplicateItems.push(item); } else { uniqueItems.push(item); } }); console.log("重复attr的对象:", duplicateItems); console.log("唯一attr的对象:", uniqueItems);
注意事项:
- 以上方法都会保留原数组中的对象引用,如果你需要深拷贝对象,可以在
push或filter时用JSON.parse(JSON.stringify(item))处理; - 如果数组中有多个重复的
attr值(比如4个attr=5的对象),所有对应的对象都会被纳入duplicateItems数组,符合需求。
内容的提问来源于stack exchange,提问作者Jasbir Rana
相关产品推荐
相关产品推荐

