# 集合结构

静态图片

集合通常是由一组无序的,不能重复的元素构成。

# 集合的特点

  • 集合通常是由一组无序的、不能重复的元素构成
  • 和数学中的集合名词比较相似,但是数学中的集合范围更大些,也允许集合中的元素重复
  • 可以将集合看成特殊的数组(没有顺序,不能重复)
    • 特殊之处在于里面的元素没有顺序,也不能重复
    • 没有顺序意味着不能通过下标值进行访问,不能重复意味着相同的对象在集合中只会存一份

# 常用方法

  • add(value): 向集合添加一个新的项
  • remove(value): 从集合中移除一个值
  • has(value): 如果值在集合中,返回 true ,否则返回 false
  • clear(): 移除集合中所有项
  • size(): 返回集合所包含元素的数量,与数组的length属性相似
  • values(): 返回一个包含集合中所有值的数组

# add 方法

// 1.add 方法
add (value) {
	// 判断当前集合是否已经包含元素
	if (this.has(value)) {
		return false
	}
	// 将元素添加到集合中
	this.items[value] = value

	return true
}
1
2
3
4
5
6
7
8
9
10
11

# has 方法


// 2.has 方法
has(value) {
	return this.items.hasOwnProperty(value)
}

1
2
3
4
5
6

# remove 方法

// 3.remove 方法
remove(value) {
	// 3-1.判断是否包含元素
	if (!this.has(value)) {
		return false
	}

	// 3-2.删除元素
	delete this.items[value]
	return true
}

1
2
3
4
5
6
7
8
9
10
11
12

# clear 方法


// 4.clear 方法
clear() {
	this.items = {}
}

1
2
3
4
5
6

# size 方法


// 5.size 方法
size () {
	return Object.keys(this.items).length
}

1
2
3
4
5
6

# values 方法


// 6.values 方法
values () {
	return Object.keys(this.items)
}

1
2
3
4
5
6

# 代码实现

class Set {
    constructor() {
        this.items = {}
    }
    
    // 1.add 方法
    add (value) {
        // 判断当前集合是否已经包含元素
        if (this.has(value)) {
            return false
        }
        // 将元素添加到集合中
        this.items[value] = value
    
        return true
    }
    
    // 2.has 方法
    has (value) {
        return this.items.hasOwnProperty(value)
    }
    
    // 3.remove 方法
    remove (value) {
        // 3-1.判断是否包含元素
        if (!this.has(value)) {
            return false
        }
    
        // 3-2.删除元素
        delete this.items[value]
        return true
    }
    // 4.clear 方法
    clear () {
        this.items = {}
    }
    // 5.size 方法
    size () {
        return Object.keys(this.items).length
    }
    // 6.values 方法
    values () {
        return Object.keys(this.items)
    }
    
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47

# 集合间的操作

  • 并集:对于给定的两个集合,返回一个包含两个集合中所有元素的新集合
  • 交集:对于给定的两个集合,返回一个包含两个集合中共有元素的新集合
  • 差集:对于给定的两个集合,返回一个包含所有存在于第一个集合且不存在与第二个集合的元素的新集合
  • 子集:验证一个给定集合是否是另一个集合的子集

静态图片

# 并集

并集其实对应数学中并集的概念

集合A 和 B的并集,表示 A ∪ B 定义如下

A∪B={x|x∈A,或x∈B}

意思是 x (元素)存在于A中,或 x 存在于 B中。

原理:

  • 首先创建一个新的集合,代表两个集合的并集
  • 遍历集合1中所有元素,并且添加到新集合中
  • 遍历集合2中所有元素,并且添加到新集合中
  • 返回新集合

// 7.union 并集
union(otherSet) {
	// 集合A: this
	// 集合B: otherSet
	// 7-1.创建新的集合
	let unionSet = new Set()

	// 7-2.将A集合中所有的元素添加到新集合中
	let values = this.values()
	for (let i = 0; i < values.length; i++) {
		unionSet.add(values[i])
	}

	// 7-3.取出B集合的元素,判断是否需要添加到新集合
	values = otherSet.values()
	for (let i = 0; i < values.length; i++) {
		unionSet.add(values[i])
	}

	return unionSet
}

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23

# 交集

交集其实对应的就是数学中的交集概念

集合A和B的交集,表示为 A ∩ B 定义如下

A∩B={x|x∈A,且x∈B}

意思是 x (元素)存在于 A 中,且 x 存在于 B中

原理:

  • 创建一个新的集合
  • 遍历集合 1 中所有的元素,判断是否该元素在集合 2 中
  • 同时在集合 2 中,将该元素加到新集合中
  • 返回新集合

// 8.交集
intersection(otherSet) {
	// 集合A: this
	// 集合B: otherSet
	// 8-1.创建一个新的集合
	let intersectionSet = new Set()

	// 8-2.从A中取出元素,判断是否同时存在集合B中
	let values = this.values()

	for (let i = 0; i < values.length; i++) {
		let item = values[i]
		if (otherSet.has(item)) {
			intersectionSet.add(item)
		}
	}

	return intersectionSet
}

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21

# 差集

差集对应数学中的差集概念

集合 A 和 B 的差,表示为 A - B 定义如下:

{x∣x∈A,且x∉B}

意思是 x (元素)存在于 A 中,且 x 不存在于 B 中

原理:

  • 创建一个新的集合
  • 遍历集合 1 中所有的元素,判断是否在集合 2 中
  • 不存在于集合 2 中,将该元素添加到新集合中
  • 返回新集合
// 9.差集
difference(otherSet) {
	// 9-1.创建新的集合
	let differenceSet = new Set()

	// 9-2.取出A集合中的元素,判断是否同时存在于B中,不存在B中的放到新集合里
	let values = this.values()
	for (let i = 0; i < values.length; i++) {
		let item = values[i]
		if (!otherSet.has(item)) {
			differenceSet.add(item)
		}
	}
	return differenceSet
}

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16

# 子集

子集对应数学中子集的概念

集合 A 是 B 的子集(或集合 B 包含了 A),表示为 A ⊆ B

若∀a∈A,均有a∈B,则A⊆B

意思是集合A 中的每一个a(元素),也需要存在于B中

原理:

  • 判断集合 A是否大于集合 2,如果大于,那么肯定不是集合2的子集
  • 不大于情况:
    • 判断集合1中的元素是否都在集合2中存在
    • 存在,那么是集合2的子集
    • 有一个不存在,那么不是集合2的子集

// 10.子集
subset(otherSet) {
	// 10-1.遍历A中所有的元素,如果发现集合A中有一个元素在集合B中不存在,就返回false
	// 如果遍历完了A,依然没有返回false 返回 true

	let values = this.values()
	for (let i = 0; i < values.length; i++) {
		let item = values[i]
		if (!otherSet.has(item)) {
			return false
		}
	}

	return true
}

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17

# 完整代码

	class Set {
	constructor() {
		this.items = {}
	}

	// 1.add 方法
	add (value) {
		// 判断当前集合是否已经包含元素
		if (this.has(value)) {
			return false
		}
		// 将元素添加到集合中
		this.items[value] = value

		return true
	}

	// 2.has 方法
	has (value) {
		return this.items.hasOwnProperty(value)
	}

	// 3.remove 方法
	remove (value) {
		// 3-1.判断是否包含元素
		if (!this.has(value)) {
			return false
		}

		// 3-2.删除元素
		delete this.items[value]
		return true
	}
	// 4.clear 方法
	clear () {
		this.items = {}
	}
	// 5.size 方法
	size () {
		return Object.keys(this.items).length
	}
	// 6.values 方法
	values () {
		return Object.keys(this.items)
	}
	// 7.union 并集
	union(otherSet) {
		// 集合A: this
		// 集合B: otherSet
		// 7-1.创建新的集合
		let unionSet = new Set()

		// 7-2.将A集合中所有的元素添加到新集合中
		let values = this.values()
		for (let i = 0; i < values.length; i++) {
			unionSet.add(values[i])
		}

		// 7-3.取出B集合的元素,判断是否需要添加到新集合
		values = otherSet.values()
		for (let i = 0; i < values.length; i++) {
			unionSet.add(values[i])
		}

		return unionSet
	}

	// 8.交集
	intersection(otherSet) {
		// 集合A: this
		// 集合B: otherSet
		// 8-1.创建一个新的集合
		let intersectionSet = new Set()

		// 8-2.从A中取出元素,判断是否同时存在集合B中, 存在,就放到新集合中
		let values = this.values()

		for (let i = 0; i < values.length; i++) {
			let item = values[i]
			if (otherSet.has(item)) {
				intersectionSet.add(item)
			}
		}

		return intersectionSet
	}

	// 9.差集
	difference(otherSet) {
		// 9-1.创建新的集合
		let differenceSet = new Set()

		// 9-2.取出A集合中的元素,判断是否同时存在于B中,不存在B中的放到新集合里
		let values = this.values()
		for (let i = 0; i < values.length; i++) {
			let item = values[i]
			if (!otherSet.has(item)) {
				differenceSet.add(item)
			}
		}
		return differenceSet
	}

	// 10.子集
	subset(otherSet) {
		// 10-1.遍历A中所有的元素,如果发现集合A中有一个元素在集合B中不存在,就返回false
		// 如果遍历完了A,依然没有返回false 返回 true

		let values = this.values()
		for (let i = 0; i < values.length; i++) {
			let item = values[i]
			if (!otherSet.has(item)) {
				return false
			}
		}

		return true
	}


}

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122