JavaScript 如何无需嵌套循环提取两个数组的公共元素
JavaScript 数组取交集的高性能实现方案
你可以通过ES6的Set数据结构实现无嵌套循环的高效交集计算,Set的has()方法时间复杂度为O(1),整体方案的时间复杂度仅为O(n+m)(n、m为两个数组的长度),远优于嵌套循环的O(n*m)。
基础实现代码
注意:原示例中的数组元素为字符串,实际运行需要添加引号包裹,否则会被识别为未定义变量。
let listOne = ['Bill', 'Joe', 'Trever', 'Neil', 'Jim', 'Pam', 'Michael'] let listTwo = ['Petter', 'Pam', 'Steven', 'Jim', 'Michael', 'Scott'] // 优先将长度更短的数组转为Set,降低内存占用 const tempSet = new Set(listOne.length > listTwo.length ? listTwo : listOne) // 过滤长数组,保留同时存在于Set中的元素 const intersection = (listOne.length > listTwo.length ? listOne : listTwo).filter(item => tempSet.has(item)) console.log(intersection) // 输出结果:['Jim', 'Pam', 'Michael']
支持双数组预处理过滤的通用实现
如果需要同时对两个数组做自定义过滤后再取交集,可以封装为通用函数:
/** * 取两个数组的交集 * @param {Array} arr1 第一个数组 * @param {Array} arr2 第二个数组 * @param {Function} filterFn 可选:双数组统一的预处理过滤函数 * @returns {Array} 交集结果 */ function getIntersection(arr1, arr2, filterFn = null) { // 先对两个数组执行统一的过滤逻辑 const processed1 = filterFn ? arr1.filter(filterFn) : arr1 const processed2 = filterFn ? arr2.filter(filterFn) : arr2 const compareSet = new Set(processed1.length > processed2.length ? processed2 : processed1) return (processed1.length > processed2.length ? processed1 : processed2).filter(item => compareSet.has(item)) } // 示例:过滤掉长度小于3的元素后再取交集 const res = getIntersection(listOne, listTwo, (item) => item.length >= 3)
内容的提问来源于stack exchange,提问作者jgrewal
相关产品推荐
相关产品推荐

