# 数组交集差集并集

有任意两个数组,每个数组里面的元素不重复,找出它们的交集、差集和并集。

# 交集、差集和并集是什么鬼?

  1. 交集

由所有属于集合 A 且属于集合 B 的元素所组成的集合,叫做集合 A 与集合 B 的交集(intersection),记作 A∩B

交集百度百科

  1. 差集

以属于 A 而不属于 B 的元素为元素的集合成为 A 与 B 的差。(本文栗子,还会求出属于 B 不属于 A 的集合)

差集百度百科

  1. 并集

给定两个集合 A,B,把他们所有的元素合并在一起组成的集合,叫做集合 A 与集合 B 的并集,记作 A∪B,读作 A 并 B。

并集百度百科

# includes 判断是否包含:

let one = [1, 2, 3, 4, 5]
let two = [2, 3, 4, 7]
const intersection = (a, b) => {
	// a b数组的交集
	let arr = a.filter(v => {
		// b是否包含a的元素,包含就返回true,交集
		return b.includes(v)
	})
	return arr
}
const difference = (a, b) => {
	// a b 数组的差集
	let arr = [...a, ...b].filter(v => {
		// a和b是否包含v 不包含返回!false  出现有一个不包含(另一个数组就包含 找到差值),就返回true 添加进数组
		return !a.includes(v) || !b.includes(v)
	})
	return arr
}

const unionArr = (a, b) => {
	return Array.from(new Set([...a, ...b])) // 并集可以理解为合并数组去重,直接用set即可
}
console.log(difference(one, two), intersection(one, two), unionArr(one, two))
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23

事实上,还可以改成indexOf来判断是否包含,但是要注意indexOf是不能识别NaN的。

# 使用 Set 来判断:

function arrSet(a, b, type) {
	let set
	a = new Set(a)
	b = new Set(b)
	if (type === 'difference') {
		// ab数组差集
		set = new Set([...a, ...b].filter(x => !b.has(x) || !a.has(x)))
	} else if (type === 'intersection') {
		// ab数组交集
		set = new Set([...a].filter(x => b.has(x)))
	} else {
		// ab数组并集
		set = new Set([...a, ...b])
	}
	return Array.from(set) // 转为set
}
console.log(
	arrSet(one, two, 'difference'),
	arrSet(one, two, 'intersection'),
	arrSet(one, two, 'union')
)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21