如何高效运用 Set 和 Array.prototype.filter 找出两个数组交集的公共业务元素?

2026-05-07 02:051阅读0评论SEO资源
  • 内容介绍
  • 相关推荐

本文共计611个文字,预计阅读时间需要3分钟。

如何高效运用 Set 和 Array.prototype.filter 找出两个数组交集的公共业务元素?

使用 Set 和 filter 提取两个数组的公共项,核心是将一个数组转换为 Set 提高查找效率,再用 filter 筛选出另一个数组中存在于 Set 中的元素。时间复杂度从 O(m*n) 降低到 O(m+n),适合大型数组。

构造 Set 并筛选公共元素

将其中一个数组(通常是较短或更稳定的那个)转为 Set,利用 Set 的 has 方法实现 O(1) 查找:

const arr1 = [{ id: 1, name: '订单' }, { id: 2, name: '用户' }]; const arr2 = [{ id: 2, name: '客户' }, { id: 3, name: '商品' }]; // 假设按 id 匹配 const idSet = new Set(arr2.map(item => item.id)); const common = arr1.filter(item => idSet.has(item.id)); // → [{ id: 2, name: '用户' }]

处理对象数组:提取关键字段再比对

业务中多数是对象数组,需先统一提取比对字段(如 idcodesku),避免直接用对象引用比较(永远为 false):

  • 不要写 arr1.filter(item => arr2.includes(item)) —— 对象引用不同,结果为空
  • 优先用 map().flat()flatMap 处理嵌套结构(如权限数组中的 resources 字段)
  • 若需多字段联合唯一(如 tenantId + resourceId),可用字符串拼接生成 key:`${item.tenantId}-${item.resourceId}`

去重 + 保序:结果自动唯一且保持 arr1 原顺序

Set 本身去重,filter 按 arr1 顺序遍历,因此结果天然满足两个条件:

  • 每个匹配项只出现一次(即使 arr2 中有重复 id)
  • 输出顺序与 arr1 一致,符合前端渲染/校验等业务逻辑预期
  • 若需按 arr2 顺序返回,可改用 arr2.filter(item => idSetFromArr1.has(item.id))

扩展:支持自定义匹配逻辑(非简单字段相等)

如果业务规则更复杂(如模糊匹配、区间重叠、状态兼容),可在 filter 回调中封装判断函数,Set 仍负责主键预检提速:

const validCodes = new Set(['A001', 'B002', 'C003']); const products = [ { code: 'A001-X', type: 'normal' }, { code: 'B002-Y', type: 'special' } ]; const commonByPrefix = products.filter(p => validCodes.has(p.code.substring(0, 4)) // 利用 Set 快速判断前缀 );

本文共计611个文字,预计阅读时间需要3分钟。

如何高效运用 Set 和 Array.prototype.filter 找出两个数组交集的公共业务元素?

使用 Set 和 filter 提取两个数组的公共项,核心是将一个数组转换为 Set 提高查找效率,再用 filter 筛选出另一个数组中存在于 Set 中的元素。时间复杂度从 O(m*n) 降低到 O(m+n),适合大型数组。

构造 Set 并筛选公共元素

将其中一个数组(通常是较短或更稳定的那个)转为 Set,利用 Set 的 has 方法实现 O(1) 查找:

const arr1 = [{ id: 1, name: '订单' }, { id: 2, name: '用户' }]; const arr2 = [{ id: 2, name: '客户' }, { id: 3, name: '商品' }]; // 假设按 id 匹配 const idSet = new Set(arr2.map(item => item.id)); const common = arr1.filter(item => idSet.has(item.id)); // → [{ id: 2, name: '用户' }]

处理对象数组:提取关键字段再比对

业务中多数是对象数组,需先统一提取比对字段(如 idcodesku),避免直接用对象引用比较(永远为 false):

  • 不要写 arr1.filter(item => arr2.includes(item)) —— 对象引用不同,结果为空
  • 优先用 map().flat()flatMap 处理嵌套结构(如权限数组中的 resources 字段)
  • 若需多字段联合唯一(如 tenantId + resourceId),可用字符串拼接生成 key:`${item.tenantId}-${item.resourceId}`

去重 + 保序:结果自动唯一且保持 arr1 原顺序

Set 本身去重,filter 按 arr1 顺序遍历,因此结果天然满足两个条件:

  • 每个匹配项只出现一次(即使 arr2 中有重复 id)
  • 输出顺序与 arr1 一致,符合前端渲染/校验等业务逻辑预期
  • 若需按 arr2 顺序返回,可改用 arr2.filter(item => idSetFromArr1.has(item.id))

扩展:支持自定义匹配逻辑(非简单字段相等)

如果业务规则更复杂(如模糊匹配、区间重叠、状态兼容),可在 filter 回调中封装判断函数,Set 仍负责主键预检提速:

const validCodes = new Set(['A001', 'B002', 'C003']); const products = [ { code: 'A001-X', type: 'normal' }, { code: 'B002-Y', type: 'special' } ]; const commonByPrefix = products.filter(p => validCodes.has(p.code.substring(0, 4)) // 利用 Set 快速判断前缀 );