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
相关产品推荐
相关产品推荐

