TypeScript判断两个数组是否存在公共元素的更优雅实现方式
判断两个数组是否存在公共元素的优雅实现(TypeScript/JavaScript)
问题背景
你现在用双重循环判断两个数组是否有公共元素,希望找到更优雅的实现方式,参考Java中lst1.stream().anyMatch(c -> lst2.contains(c))的写法,当前的双重循环代码如下:
let lst1 : string [] = ["aaa", "bbb", "ccc"]; let lst2 : string [] = ["ddd", "eee", "bbb"]; // 1 match at "bbb" let matches : boolean = false; for (let a of lst1) { for (let b of lst2) { if (a == b) { matches = true; } } }
优雅实现方式
1. some() + includes()(最贴近Java Stream写法)
TypeScript/JavaScript里的Array.some()和Java的anyMatch()逻辑一致——只要数组里有一个元素满足条件就返回true;搭配Array.includes()判断元素是否存在,一行代码就能搞定:
const lst1: string[] = ["aaa", "bbb", "ccc"]; const lst2: string[] = ["ddd", "eee", "bbb"]; const hasCommon = lst1.some(item => lst2.includes(item)); console.log(hasCommon); // 输出 true
这种写法简洁直观,和你熟悉的Java写法完全对应,而且找到第一个匹配项就会停止遍历,不会像双重循环那样可能遍历所有元素。
2. 用Set优化性能(适合大数据量场景)
如果两个数组数据量较大,includes()的O(n)时间复杂度会让整体性能降到O(n*m),这时可以把其中一个数组转成Set,利用Set的has()方法O(1)的查询性能,把整体复杂度降到O(n+m):
const lst1: string[] = ["aaa", "bbb", "ccc"]; const lst2: string[] = ["ddd", "eee", "bbb"]; const set2 = new Set(lst2); const hasCommon = lst1.some(item => set2.has(item)); console.log(hasCommon); // 输出 true
这种方式在处理大型数组时性能提升明显,是更高效的选择。
3. filter()判断交集长度(直观但性能一般)
也可以过滤出两个数组的交集,再判断交集是否为空:
const lst1: string[] = ["aaa", "bbb", "ccc"]; const lst2: string[] = ["ddd", "eee", "bbb"]; const intersection = lst1.filter(item => lst2.includes(item)); const hasCommon = intersection.length > 0; console.log(hasCommon); // 输出 true
不过这种方式会遍历完整个数组并生成交集数组,性能不如前两种,适合不需要考虑性能的小型数组场景。
内容的提问来源于stack exchange,提问作者chris01
相关产品推荐
相关产品推荐

