用 filter + set 实现交集和差集可将时间复杂度从 o(n×m) 降至 o(n+m):交集自动去重,差集保留原序与重复;注意 nan 在 set 中特殊相等、对象需深比较。

用 filter + Set 做交集:别直接用 includes
直接对数组调用 filter 并用 includes 判断是否在另一个数组中,时间复杂度是 O(n×m),数据一多就卡。换成 Set 后查存在性是 O(1),整体降到 O(n+m)。
实操建议:
- 先将第二个数组转为
Set,再传入filter回调里使用has -
Set自动去重,如果原数组有重复,交集结果也只保留一份(符合数学定义) - 注意原始数组元素类型要能被
Set正确识别——对象引用不等价,{a:1}和{a:1}是两个不同值
const a = [1, 2, 3, 4]; const b = [3, 4, 5, 6]; const setB = new Set(b); const intersection = a.filter(x => setB.has(x)); // [3, 4]
用 filter + Set 做差集(a 减 b):顺序和重复都保留
差集不是“去掉 b 中所有元素”,而是“保留 a 中不在 b 中的元素”。filter 天然保持原数组顺序,且不改变重复项——这点比用 Set 构造再转回数组更可控。
实操建议:
- 同样先建
Set,避免每次filter都遍历 b 数组 - 差集方向敏感:
a.filter(x => !setB.has(x))是 a−b;反过来才是 b−a - 如果 a 本身含重复值,比如
[1,1,2]减[1],结果是[1,2](第一个 1 被过滤,第二个保留)
const a = [1, 1, 2, 3]; const b = [1, 4]; const setB = new Set(b); const difference = a.filter(x => !setB.has(x)); // [1, 2, 3]
filter + Set 的边界情况:null、undefined、NaN 怎么办
Set 能存 null 和 undefined,但对 NaN 有特殊行为:多个 NaN 在 Set 中只存一个,且 set.has(NaN) 返回 true——这是 ES 规范定的,和 === 不同。
常见坑点:
- 如果数组含
NaN,用Set判断没问题;但若手动用includes就会失效([NaN].includes(NaN)是true,但逻辑上容易误判) -
null和undefined在Set中是不同值,new Set([null, undefined])大小为 2 - 如果数据可能为空或非原始类型,别假设
Set能自动深比较——它只看引用或原始值
NaN 的语义差异,还有把 Set 当成“万能去重容器”却忘了它不处理嵌套结构。










