JavaScript 基础
Document
运算符
深入数据和类型
函数进阶
原型、继承
类
浏览器存储
Web API
事件
错误处理
异步编程
网络请求
模块
练习
实例
工具与规范
软件架构模式
设计模式
Set
Set 是一个集合类型,它跟数组很像,但里面的元素只能出现一次。
以下代码创建一个空集合,并往里面添加元素。
$$jsdemo$$
$$edit$$
let set = new Set() // 创建空集合
set.add(1) // 将元素添加到数组中
set.add(2)
set.add(2) // 只会存在一个数字
console.log(set) // Set(3) {1, 2}
属性和方法
Set 类型的属性和方法比较少,因此都列在了以下表格中。
属性 | 描述 |
---|---|
size | 返回集合的元素数量。 |
方法 | 描述 |
---|---|
new Set([iterable]) | 创建一个集合,可选地接收一个可迭代对象并转换为集合。 |
add(item) | 添加一个元素并返回自身。 |
delete(item) | 删除一个元素,如果元素存在返回 true 否则返回 false。 |
has(item) | 判断元素是否存在于集合中。 |
clear() | 清空集合。 |
集合转数组
使用 Array.from
$$jsdemo$$
$$edit$$
let students = new Set(["鸣人", "柯南", "路飞"])
let arr = Array.from(students)
alert(Array.isArray(arr)) // true
alert(arr) // 鸣人,柯南,路飞
使用展开语法
$$jsdemo$$
$$edit$$
let students = new Set(["鸣人", "柯南", "路飞"])
let arr = [...students]
alert(Array.isArray(arr)) // true
alert(arr) // 鸣人,柯南,路飞
集合和数组的区别
$$tip
这里仅仅介绍一些比较明显且重要的细节,一些细微的点可能不会提及。
$$
长度
集合的长度属性是 size
,而数组是 length
。
集合没有顺序
无法通过下标获取
集合中保存的元素不会按顺序排列,因此也无法通过下标获取其中的值。
$$jsdemo$$
$$edit$$
let set = new Set([1, 2, 3, 4, 5])
alert(set[0]) // undefined
alert(set[1]) // undefined
for … in 无效
自然也无法使用 for ... in
循环下标。
$$jsdemo$$
$$edit$$
let set = new Set([1, 2, 3, 4, 5])
for (let i in set) {
alert(i) // 不会被执行
}
不过 for ... of
依旧能正常作用于集合。
$$jsdemo$$
$$edit$$
let set = new Set([1, 2, 3, 4, 5])
for (let item of set) {
alert(item)
}
集合运算
集合运算是一个基本的数学操作,可惜的是,JavaScript 没有提供集合运算的方法,但我们可以自己实现。
$$tip
集合运算的实现并不唯一,你也可以根据自己的想法来实现。
$$
交集
交集指的是多个集合中共同存在的部分。
比如要评三好学生,要颁奖给同时报了几个兴趣班的同学,适用交集运算。
$$jsdemo$$
$$edit$$
// 交集
function intersection(a, b) {
let result = new Set()
for (let x of b) {
if (a.has(x)) {
result.add(x)
}
}
return result
}
let classA = new Set(["小樱", "鸣人", "路飞"])
let classB = new Set(["鸣人", "路飞", "柯南"])
let intersectionClass = intersection(classA, classB)
console.log(intersectionClass) // {'鸣人', '路飞'}
并集
并集指的是将多个集合合并成一个集合。
比如要统计几个兴趣班总的同学名单,就要过滤掉重复的同学,此时适用并集运算。
$$jsdemo$$
$$edit$$
// 并集
function union(a, b) {
return new Set([...a, ...b])
}
let classA = new Set(["小樱", "鸣人", "路飞"])
let classB = new Set(["鸣人", "路飞", "柯南"])
let unionClass = union(classA, classB)
console.log(unionClass) // {'小樱', '鸣人', '路飞', '柯南'}
差集
假如存在集合 A、B,那么 A 对 B 进行差集运算就意味着在仅在 A 存在,不存在于 B 的部分。
$$tip
与并集交集运算顺序不影响结果不一样。差集会因运算顺序不同,结果也会不同。
$$
$$jsdemo$$
$$edit$$
// 差集
function difference(a, b) {
let result = new Set(a)
for (let x of b) {
result.delete(x)
}
return result
}
let classA = new Set(["小樱", "鸣人", "路飞"])
let classB = new Set(["鸣人", "路飞", "柯南"])
let differenceClass = difference(classA, classB)
console.log(differenceClass) // {'小樱'}
对称差
对称差指的是多个集合中仅在一个集合中存在的部分。
$$jsdemo$$
$$edit$$
// 差集
function difference(a, b) {
let result = new Set(a)
for (let x of b) {
result.delete(x)
}
return result
}
// 对称差
function symmetricDifference(a, b) {
return new Set([...difference(a, b), ...difference(b, a)])
}
let classA = new Set(["小樱", "鸣人", "路飞"])
let classB = new Set(["鸣人", "路飞", "柯南"])
let sdClass = symmetricDifference(classA, classB)
console.log(sdClass) // {'小樱', '柯南'}
练习
- 以下定义了多个数组,将其放到一个集合中。
let nums1 = [2, 4, 6, 7]
let nums2 = [3, 4, 6, 1]
let nums3 = [1, 2, 5, 2]
$$answer
$$jsdemo$$
$$edit$$
let nums1 = [2, 4, 6, 7]
let nums2 = [3, 4, 6, 1]
let nums3 = [1, 2, 5, 2]
let numbers = new Set([...nums1, ...nums2, ...nums3])
console.log(numbers)
$$
- 存在三个班级的集合,需要给同时上三个班(交集)的同学奖励助学金,求出这些同学。
let englishClass = new Set(["鸣人", "路飞", "柯南"])
let mathClass = new Set(["小樱", "柯南", "鸣人"])
let sportClass = new Set(["鸣人", "艾伦"])
$$answer
$$jsdemo$$
$$edit$$
let englishClass = new Set(["鸣人", "路飞", "柯南"])
let mathClass = new Set(["小樱", "柯南", "鸣人"])
let sportClass = new Set(["鸣人", "艾伦"])
// 交集
function intersection(a, b) {
let result = new Set()
for (let x of b) {
if (a.has(x)) {
result.add(x)
}
}
return result
}
let result = intersection(englishClass, mathClass)
result = intersection(sportClass, result)
console.log(result) // Set(1) {'鸣人'}
$$