JavaScript中Set天然适合集合运算,因自动去重、支持迭代且增删查近O(1);并集用[...a,...b]展开去重,交集遍历小集提升性能,差集过滤a中不在b的元素,对称差集可用组合或一次遍历实现。

JavaScript 中的 Set 天然适合实现集合运算,因为它自动去重、支持迭代,且增删查时间复杂度接近 O(1)。用函数式风格封装并集、交集、差集,代码简洁、可复用、无副作用。
并集(Union):合并两个集合,去除重复元素
并集是将两个集合的所有元素合并后去重。最直观的方式是遍历第二个集合,逐个添加到第一个集合的副本中。
推荐写法(不修改原集合,返回新 Set):
const union = (a, b) => new Set([...a, ...b]);
说明:
• [...a, ...b] 展开两个 Set 为数组,自动保留所有值(包括重复项);
• 再用 new Set(...) 去重,得到并集;
• 若需兼容只接受可迭代对象的场景,也可写成:new Set([...a].concat([...b])),效果一致。
交集(Intersection):取两个集合共有的元素
交集要求某个元素同时存在于两个集合中。只需遍历较小的集合(提升性能),检查是否在另一个集合中存在即可。
函数式实现:
const intersection = (a, b) => {
const [smaller, larger] = a.size <= b.size ? [a, b] : [b, a];
return new Set([...smaller].filter(x => larger.has(x)));
};
说明:
• 先判断大小,用较小集合做主遍历,减少 .has() 调用次数;
• .filter(x => larger.has(x)) 筛出共同元素;
• 包裹为 new Set(...) 返回新集合,保持不可变性。
差集(Difference):a 减去 b,即属于 a 但不属于 b 的元素
差集也叫相对补集,逻辑清晰:遍历 a,保留那些不在 b 中的元素。
简洁实现:
const difference = (a, b) => new Set([...a].filter(x => !b.has(x)));
说明:
• 不需要比较集合大小,因为只遍历 a;
• !b.has(x) 判断 x 是否不属于 b;
• 同样返回全新 Set,不影响输入。
扩展:对称差集(Symmetric Difference)
对称差集 = 并集 − 交集 = 属于 a 或 b,但不同时属于两者。可用已有函数组合:
const symmetricDifference = (a, b) => difference(union(a, b), intersection(a, b));
或更高效的一次遍历写法:
const symmetricDifference = (a, b) => {
const result = new Set();
for (const x of a) if (!b.has(x)) result.add(x);
for (const x of b) if (!a.has(x)) result.add(x);
return result;
};
该版本避免创建中间集合,空间更友好。
这些函数都接受任意可迭代对象(如数组、字符串、Map.keys() 等)作为参数,只需先转为 Set 即可通用使用。例如:intersection(new Set([1,2,3]), [2,3,4]) 需先统一为 Set —— 可加一层适配:const toSet = it => new Set(it),再调用 intersection(toSet(a), toSet(b))。

















