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

JavaScript如何实现多对象数组取交集且兼容空数组、可扩展?

解决方案

实现思路

  • 抽象通用函数,支持传入任意数量的对象数组,无需硬编码判断条件
  • 第一步先过滤所有空数组,仅保留有数据的有效数组
  • 统计每个id在多少个有效数组中出现(同数组内重复id仅计数1次)
  • 筛选出出现次数等于有效数组总数的id,对应对象即为交集结果

实现代码

// 通用交集函数,支持传入任意数量的对象数组,按id匹配
function getIntersectionById(...arrays) {
  // 过滤掉空数组和非数组类型的无效输入
  const validArrays = arrays.filter(arr => Array.isArray(arr) && arr.length > 0)
  // 边界处理:无有效数组返回空,仅一个有效数组直接返回
  if (validArrays.length === 0) return []
  if (validArrays.length === 1) return validArrays[0]

  // 统计每个id在多少个有效数组中存在
  const idCount = new Map()
  validArrays.forEach(arr => {
    // 先对当前数组的id去重,避免同数组重复id导致计数错误
    const uniqueIds = new Set(arr.map(item => item.id))
    uniqueIds.forEach(id => {
      idCount.set(id, (idCount.get(id) || 0) + 1)
    })
  })

  // 取第一个有效数组为基准,返回id计数等于有效数组总数的对象
  const targetCount = validArrays.length
  return validArrays[0].filter(item => idCount.get(item.id) === targetCount)
}

// 测试用例
let datasOne = [
  { id: 1, name: 'Gustavo' },
  { id: 2, name: 'Ana' },
  { id: 3, name: 'Luiz' },
  { id: 8, name: 'Alice' }
]
let datasTwo = [
  { id: 1, name: 'Gustavo' },
  { id: 3, name: 'Luiz' },
  { id: 8, name: 'Alice' }
]
let datasThree = [
  { id: 1, name: 'Gustavo' },
  { id: 3, name: 'Luiz' },
  { id: 2, name: 'Ana' },
  { id: 5, name: 'Kelly' },
  { id: 4, name: 'David' }
]

// 调用方式,后续新增数组直接往参数里加即可
const filtered = getIntersectionById(datasOne, datasTwo, datasThree)
console.log(filtered)
// 输出:[ { id: 1, name: 'Gustavo' }, { id: 3, name: 'Luiz' } ]

方案优势

  • 扩展性极强:后续新增datasFour等更多对比数组,直接在调用函数时追加参数即可,无需修改逻辑代码
  • 无冗余判断:自动处理所有空数组场景,覆盖所有分支逻辑
  • 性能更优:使用Map和Set做统计,时间复杂度为O(N)(N为所有数组的元素总数量),远优于原写法嵌套过滤的O(n^k)复杂度
  • 兼容边界情况:自动过滤非数组类型的无效输入,鲁棒性更强

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.02 04:06:03