You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何检测对象数组中是否存在重复对象?

判断对象数组是否存在重复对象的解决方案

核心问题说明

你尝试的代码之所以无法正确检测重复对象,是因为对象是引用类型,Array.includes() 比较的是对象的内存地址而非内容。哪怕两个对象的键值对完全一致,它们也是不同的引用,会被当成不同元素处理,导致最终返回的数组和原数组长度一致,无法判断重复。

而且,检测对象重复完全不需要依赖forEach/for循环,有多种更简洁高效的实现方式。

解决方案

方法1:利用JSON.stringify与Set(简单场景)

将每个对象转为JSON字符串,利用Set自动去重的特性,比较原数组长度与Set的大小即可判断是否存在重复。

function hasDuplicateObjects<T>(array: T[]): boolean {
  const stringifiedItems = array.map(item => JSON.stringify(item));
  return new Set(stringifiedItems).size !== array.length;
}

// 测试示例
const arr = [
     { nr:10, name: 'aba' },
     { nr:11, name: 'cba' },
     { nr:10, name: 'aba' }
];
const arr2 = [
         { year:2020, city: 'Aaa' },
         { year:2010, city: 'Bbb' },
         { year:2020, city: 'Aaa' }
    ];

console.log(hasDuplicateObjects(arr)); // 输出 true
console.log(hasDuplicateObjects(arr2)); // 输出 true

⚠️ 注意:该方法有局限性——如果两个对象的键值对内容相同但属性顺序不同(比如{a:1, b:2}和{b:2, a:1}),JSON.stringify会生成不同的字符串,导致误判为不同对象。如果需要处理这种场景,要先统一对象属性的顺序再转字符串。

方法2:自定义对象比较函数(通用场景)

实现一个深度比较对象内容的函数,结合Array.some()和Array.findIndex()来检测是否存在内容重复的对象,这种方法更可靠,能处理属性顺序不同的情况。

// 自定义对象深度比较函数
function isObjectEqual(a: any, b: any): boolean {
  // 引用相同直接返回true
  if (a === b) return true;
  // 非对象类型或null直接比较值
  if (typeof a !== 'object' || typeof b !== 'object' || a == null || b == null) {
    return a === b;
  }
  // 比较属性数量
  const keysA = Object.keys(a);
  const keysB = Object.keys(b);
  if (keysA.length !== keysB.length) return false;
  // 逐个比较属性值
  for (const key of keysA) {
    if (!keysB.includes(key) || !isObjectEqual(a[key], b[key])) {
      return false;
    }
  }
  return true;
}

// 检测重复对象的函数
function hasDuplicateObjects<T>(array: T[]): boolean {
  return array.some((item, index) => {
    // 查找当前索引之后是否有内容相同的对象
    return array.findIndex((otherItem, otherIndex) => {
      return otherIndex > index && isObjectEqual(item, otherItem);
    }) !== -1;
  });
}

// 测试示例
console.log(hasDuplicateObjects(arr)); // 输出 true
console.log(hasDuplicateObjects(arr2)); // 输出 true

对你原有代码的修改

如果一定要基于你写的循环逻辑实现,需要将result.includes(item)替换为自定义的内容比较:

function removeDuplicatesAndCheck<T>(array: T[]): boolean {
  const result: T[] = [];
  for (const item of array) {
    // 检查结果数组中是否已有内容相同的对象
    const hasDuplicate = result.some(existing => isObjectEqual(existing, item));
    if (!hasDuplicate) {
      result.push(item);
    }
  }
  // 返回是否存在重复(去重后长度与原数组不同则存在重复)
  return result.length !== array.length;
}

内容的提问来源于stack exchange,提问作者VMG

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.08 18:05:17