数组交集并集差集
实现两个数组的交集、并集、差集运算
问题
给定两个数组,实现它们的交集、并集、差集运算。
解答
使用 Set 实现
const arr1 = [1, 2, 3, 4, 5];
const arr2 = [3, 4, 5, 6, 7];
// 交集:两个数组都有的元素
function intersection(a, b) {
const setB = new Set(b);
return [...new Set(a)].filter(x => setB.has(x));
}
// 并集:两个数组所有元素(去重)
function union(a, b) {
return [...new Set([...a, ...b])];
}
// 差集:在 a 中但不在 b 中的元素
function difference(a, b) {
const setB = new Set(b);
return [...new Set(a)].filter(x => !setB.has(x));
}
console.log(intersection(arr1, arr2)); // [3, 4, 5]
console.log(union(arr1, arr2)); // [1, 2, 3, 4, 5, 6, 7]
console.log(difference(arr1, arr2)); // [1, 2]
对称差集
// 对称差集:只在其中一个数组中出现的元素
function symmetricDifference(a, b) {
const setA = new Set(a);
const setB = new Set(b);
return [
...a.filter(x => !setB.has(x)),
...b.filter(x => !setA.has(x))
];
}
console.log(symmetricDifference(arr1, arr2)); // [1, 2, 6, 7]
处理对象数组
const users1 = [{ id: 1 }, { id: 2 }, { id: 3 }];
const users2 = [{ id: 2 }, { id: 3 }, { id: 4 }];
// 通过指定 key 比较
function intersectionBy(a, b, key) {
const keys = new Set(b.map(item => item[key]));
return a.filter(item => keys.has(item[key]));
}
function differenceBy(a, b, key) {
const keys = new Set(b.map(item => item[key]));
return a.filter(item => !keys.has(item[key]));
}
console.log(intersectionBy(users1, users2, 'id')); // [{ id: 2 }, { id: 3 }]
console.log(differenceBy(users1, users2, 'id')); // [{ id: 1 }]
自定义比较函数
// 更灵活的实现,支持自定义比较逻辑
function intersectionWith(a, b, comparator) {
return a.filter(x => b.some(y => comparator(x, y)));
}
function differenceWith(a, b, comparator) {
return a.filter(x => !b.some(y => comparator(x, y)));
}
const result = intersectionWith(users1, users2, (a, b) => a.id === b.id);
console.log(result); // [{ id: 2 }, { id: 3 }]
关键点
- Set 的
has()方法时间复杂度为 O(1),比数组的includes()更高效 - 先将数组转为 Set 可以自动去重
- 差集不满足交换律:
A - B ≠ B - A - 对象数组需要指定比较的 key 或自定义比较函数
- 大数据量时优先使用 Set,避免嵌套循环
目录