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

如何判断对象数组间是否存在全属性匹配的公共元素并求交集?

判断两个对象数组的全属性匹配交集并获取结果

如何判断两个对象数组是否存在全属性匹配的公共元素,并获取这些交集元素?例如下面示例中,数组1里ProductId为3的对象和数组2中的对应对象完全一致。目前用双重for循环可以实现,但想知道有没有更高效的ES语法或Lodash工具函数可用。

示例代码(原双重循环思路)

array1.forEach(arr1 => {
  array2.forEach(arr2 => { 
       if (arr1.productId === arr2.productId && 
           arr1.productName === arr2.productName ...
  })
})

对象数组1

[
{
    ProductId: 50,
    ProductName: 'Test1',
    Location: 77,
    Supplier: 11,
    Quantity: 33
},
{
    ProductId: 3,
    ProductName: 'GHI',
    Location: 1,
    Supplier: 4,
    Quantity: 25
}
]

对象数组2

[
{
    ProductId: 1,
    ProductName: 'ABC',
    Location: 3,
    Supplier: 4,
    Quantity: 52
},
{
    ProductId: 2,
    ProductName: 'DEF',
    Location: 1,
    Supplier: 2,
    Quantity: 87
},
{
    ProductId: 3,
    ProductName: 'GHI',
    Location: 1,
    Supplier: 4,
    Quantity: 25
},
{
    ProductId: 4,
    ProductName: 'XYZ',
    Location:  5,
    Supplier: 6,
    Quantity: 17
}
]

一、原生ES实现方案

1. JSON.stringify快速匹配(适合简单对象)

把数组2的对象转为字符串存入Set,遍历数组1时通过字符串匹配快速判断是否存在,时间复杂度O(n+m),比双重循环高效得多。

// 预存数组2的字符串化对象
const array2StrSet = new Set(array2.map(item => JSON.stringify(item)));
// 筛选交集
const intersection = array1.filter(item => array2StrSet.has(JSON.stringify(item)));

console.log(intersection);
// 输出:[{ ProductId: 3, ProductName: 'GHI', Location: 1, Supplier: 4, Quantity: 25 }]

⚠️ 注意:仅适用于属性顺序固定、无函数/undefined等JSON不可序列化类型的对象,因为JSON.stringify的结果会受属性顺序影响。

2. 自定义深度比较(适合复杂场景)

如果对象属性顺序可能变化或包含嵌套对象,需要自定义全属性比较函数,结合filter和some实现:

// 自定义深度比较函数
function isEqual(obj1, obj2) {
  const keys1 = Object.keys(obj1);
  const keys2 = Object.keys(obj2);
  
  // 属性数量不同直接不匹配
  if (keys1.length !== keys2.length) return false;
  
  // 遍历所有属性值
  for (const key of keys1) {
    const val1 = obj1[key];
    const val2 = obj2[key];
    
    // 基础类型不相等则返回false
    if (val1 !== val2) {
      // 嵌套对象递归比较
      if (typeof val1 === 'object' && typeof val2 === 'object') {
        if (!isEqual(val1, val2)) return false;
      } else {
        return false;
      }
    }
  }
  return true;
}

// 获取交集
const intersection = array1.filter(item1 => array2.some(item2 => isEqual(item1, item2)));

这种方法更灵活,但时间复杂度仍为O(n*m)。如果数组较大,可以先通过唯一标识(如ProductId)预分组,减少后续比较次数。

二、Lodash工具函数实现

Lodash的_.intersectionWith配合_.isEqual可以直接解决问题,代码简洁且支持复杂对象的深度比较:

const _ = require('lodash');

const intersection = _.intersectionWith(array1, array2, _.isEqual);

_.isEqual会忽略属性顺序,支持嵌套对象、数组等复杂类型,是最省心的方案,推荐在已有Lodash依赖的项目中使用。

方案对比

  • JSON.stringify法:速度最快,但局限性强,仅适合简单、属性顺序固定的对象。
  • 自定义深度比较:灵活度高,但效率一般,适合需要自定义比较逻辑的场景。
  • Lodash法:简洁可靠,支持复杂对象,优先推荐。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.18 18:11:02