如何高效运用 Set 和 Array.prototype.filter 找出两个数组交集的公共业务元素?
- 内容介绍
- 相关推荐
本文共计611个文字,预计阅读时间需要3分钟。
使用 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: '用户' }]
处理对象数组:提取关键字段再比对
业务中多数是对象数组,需先统一提取比对字段(如 id、code、sku),避免直接用对象引用比较(永远为 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 和 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: '用户' }]
处理对象数组:提取关键字段再比对
业务中多数是对象数组,需先统一提取比对字段(如 id、code、sku),避免直接用对象引用比较(永远为 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 快速判断前缀 );

